杭电复试笔试 2013-2015

题目1: 简要描述:输入一个数,代表要检测的例子的个数,每个例子中:
输入两个时间(格式HH:MM:SS),前面时间减去后面时间,输出在时钟上显示的时间,格式一样,如果是以为数字的前面补零。

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
//题目1:简要描述:输入一个数,代表要检测的例子的个数,每个例子中:
//输入两个时间(格式HH:MM:SS),前面时间减去后面时间,输出在时钟上显示的时间,格式一样,如果是以为数字的前面补零。
//之前有一道题和这个类似,但是那个是求年份的,更复杂一些,这个的话,在前面时间大于后面时间的前提之下,从秒开始减
//然后设置一个标志位来判断,分和时是否需要对应建议
//最后就是要注意格式
int main()
{
    int n;//这个是例子的个数
    scanf("%d",&n);
    int h1,h2,m1,m2,s1,s2;
    int flag1=0;//这两个是用来判断秒是否需要从分中提取,和分是否需要从时中提取
    int flag2=0;
    while(n--){
        //先输入两个时间
        scanf("%d%d%d%d%d%d",&h1,&m1,&s1,&h2,&m2,&s2);
        //用m1来存最后结果
        if(s1>=s2)
            s1-=s2;
        else{
            flag1=1;
            s1=(s1+60-s2);
        }
        if((m1-flag1)>=m2)
            m1=m1-flag1-m2;
        else{
            flag2=1;
            m1=m1-flag1+60-m2;
        }
        h1=h1-flag2-h2;

        //开始输出
        printf("%02d:%02d:%02d",h1,m1,s1);//%02d就是这个意思  就是不足2位在前面补0
    }
}

题目2:简要描述:一个活动有N个人参加,一个主持人和N-1个普通参加者,其中所有的人都认识主持人,主持人也认识所有的人,主持人要求N-1个参加者说出他们在参加者中所认识的人数,如果A认识B,则B认识A,所以最少是会认识一个人,就是主持人,他们说出了自己所认识的人数后,需要判断他们中有没有人说谎。
输入:
第一行是N,N=0表示结束
第二行是N-1个数字
输出:
Lie absolutely 或者 Maybe truth
7
1 2 4 5 5 3

9
3 7 7 7 7 5 6 6
两个测试例子中第一个是Lie absolutely,第二个是Maybe truth

这道题我开始还是想的太简单了些,所以参考了两个人的文章:https://blog.csdn.net/qq_37230495/article/details/88369907
https://blog.csdn.net/gui951753/article/details/79570967

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
//题目2:简要描述:一个活动有N个人参加,一个主持人和N-1个普通参加者,其中所有的人都认识主持人,主持人也认识所有的人,
//主持人要求N-1个参加者说出他们在参加者中所认识的人数,如果A认识B,则B认识A,所以最少是会认识一个人,就是主持人,他们说出了自己所认识的人数后,需要判断他们中有没有人说谎。
//输入:
//第一行是N,N=0表示结束
//第二行是N-1个数字
//输出:
//Lie absolutely 或者 Maybe truth
//7
//1 2 4 5 5 3

//9
//3 7 7 7 7 5 6 6
//两个测试例子中第一个是Lie absolutely,第二个是Maybe truth
//这道题的思路是,首先统计N-1个人里面,那些数量大于1 ,也就是认识的人除了主持人之外,还有别的人,
//我们需要做的是,将其中一个人所说的认识的人,也就是和其他人的连线全都拆除,让他只认识主持人一个,并在其中判断之后的人有没有出差错
bool cmp(int a,int b){
    return a>b;
}
int main()
{
    int i,c=0;//c用来记录人数
    int a[100];//创建一个存储人数据的数组
    int n;//参与的人数
    bool flag=true;
    while(scanf("%d",&n)!=EOF&&n!=0){
        //开始输入认识的人
        for(i=1;i<=n-1;i++){
            scanf("%d",&a[i]);
            if(a[i]>1)
                c++;//认识除了主持人以外的人的人数
        }
        //然后对人数进行从大到小的排序,让认识最多的人放在最前面
         //再开始,对第一个人进行断线,也就是他认识x个人的话,从第二个人开始,到第x个人(这里一共是x-1个人,除去了主持人这个人)
        //,再进行排序之后,然后依次对第二个人进行断线,直到出现情况
        while(flag&&c){
        sort(a+1,a+n,cmp);
        for(i=2;i<=a[1];i++){
            a[i]--;
            if(a[i]==1)//只认识主持人了
                c--;
            if(a[i]<1)//这种情况说明有人说谎了
                flag=false;
        }
        a[1]=1;//一次循环下来,原本线最多人的人,除主持人以外全都断线了
        c--;

    }
    if(flag)
        printf("Maybe truth\n");
    else
        printf("Lie absolutely\n");
    }
}

14年的第一题
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
//大概意思就是:
//1.如果输入了一个单词,并且加上这个单词(不是第一个单词还要在前面加上一个空格),行的长度不超过80个字符,请输出它,否则请输出到新行。
//2.如果您在输入中读取了< br>,则开始一行。
//3.如果您在输入中读取了< hr>,如果不是新开启的一行,就开始一个新行,然后显示80个字符的“-”,然后开始一个新行(再次)。
//4.最后一行以换行符结尾。
int main()
{
    char str[100];
    int i,c=0;//这个代表是第一行
    while(scanf("%s",str)!=EOF){
        //开始判断他输入的是什么
        if(strcmp(str,"<br>")){
            //那就开始一行,并把新一行设置为空的东西
            printf("\n");
            c=0;

        }
        else if(strcmp(str,"<hr>")){
            if(c!=0)//如果不是新开启的一行的话
               printf("\n");
            c=0;
            for(i=0;i<80;i++)
                printf("-");
            printf("\n");

        }
        else{
            if(c+strlen(str)+1<=80){
                if(c!=0){
                    printf(" ");//加一个空格
                    c++;
                }
            }
            else{
                printf("\n");
                printf("%s",str);
                c=strlen(str);
            }
        }
    }
    printf("\n");
}

题目2:——杭电OJ1020 给定一个仅包含“A”-“Z”的字符串,我们可以使用以下方法对其进行编码:
1。每个包含k个字符的子字符串应该被编码到“kX”,其中“X”是这个子字符串中唯一的字符。 2。如果子字符串的长度为1,则“1”应被忽略。
输入 第一行包含一个整数N(1 <= N <=
100),表示测试用例的数量。下一个N行包含N个字符串。每个字符串只包含“A”-“Z”,长度小于10000。 输出
对于每个测试用例,将编码的字符串输出到一行中

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
//题目2:——杭电OJ1020
//给定一个仅包含“A”-“Z”的字符串,我们可以使用以下方法对其进行编码:
//1。每个包含k个字符的子字符串应该被编码到“kX”,其中“X”是这个子字符串中唯一的字符。
//2。如果子字符串的长度为1,则“1”应被忽略。
//输入
//第一行包含一个整数N(1 <= N <= 100),表示测试用例的数量。下一个N行包含N个字符串。每个字符串只包含“A”-“Z”,长度小于10000。
//输出
//对于每个测试用例,将编码的字符串输出到一行中
//我的思路就是,肯定是要创建一个数组来存字符的,而需要有一个'A'和数字的对应 也就是输入的x-'A'+0就是数组的位置
int main()
{
    int i,n,j,le;
    char str[100];
    char temp;
    int a[26]={0};//用来存,并且初始值都为0
    scanf("%d",&n);
    while(n--){
        scanf("%s",str);//输入字符串
        le=strlen(str);
        for(i=0;i<le;i++){
            j=str[i]-'A'+0;
            a[j]++;//对应位置加一
        }
        for(i=0;i<26;i++){
            if(a[i]==1){//说明存在且等于1
              temp=i-0+'A';//转换为字符串
            printf("%c",temp);
            }
            else if(a[i]>1){//存在且大于1
                temp=i-0+'A';
                printf("%d%c",a[i],temp);
            }
        }
    }

}

题目1:给定一个字符串,计算字符串中的数值个数并求和,其中包含了负号,若紧跟一个负号则是一个数值,则并表示这是一个负数,若紧跟的不是数字,则不表示什么。
input: 312ab-2-- -9–a outtput: 3 301

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
//题目1:给定一个字符串,计算字符串中的数值个数并求和,其中包含了负号,若紧跟一个负号则是一个数值,则并表示这是一个负数,若紧跟的不是数字,则不表示什么。
//input: 312ab-2-- -9–a
//outtput: 3 301
//这里有个点就是 如何输出一个连续的整数 靠的一个一个temp=temp*10+a[i]-'0';
//其次就是判断负数了

int main()
{
    int le,j,sum=0;
    int c=0;//记录个数
    int temp=0;
    int i=0;
    char str[100];
    //输入字符串
    scanf("%s",str);
    le=strlen(str);
    while(i<le){//这里不能用for循环了
        if(str[i]>='0'&&str[i]<='9'){
            temp=temp*10+str[i]-'0';
            i++;
        }
        else if(str[i]=='-'){//开始判断是不是负数的时候
                for(j=i+1;j<le;j++){
                if(str[j]>='0'&&str[j]<='9'){
                        temp=temp*10+str[j]-'0';
                }
                else{
                     c++;
                     sum-=temp;
                     temp=0;
                }
        }
          i=j;

        }
        else{//当出现不是负数也不是数值的时候,可以统计了
                c++;
                sum+=temp;
                temp=0;
                i++;

        }
    }
    printf("%d %d",c,sum);

}

给定一个数字矩阵,如果上下左右数值相同,则表示是一个连通的区域。求矩阵中连通块的数量。输入:先是矩阵的行数和列数接着是矩阵输出:连通块的数量
例子
5 6
4 4 4 4 4 4
4 2 3 3 1 4
4 2 2 3 1 4
4 2 3 3 1 4
4 4 4 4 4 4
输出
4
说明所有4能连起来,还有2 3 1,都有各自能连通块。

这题有两种解法,分别是使用BFS和DFS。

BFS下的(不用递归,用队列)

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<queue>
using namespace std;
//给定一个数字矩阵,如果上下左右数值相同,则表示是一个连通的区域。求矩阵中连通块的数量。输入:先是矩阵的行数和列数接着是矩阵输出:连通块的数量
//例子
//5 6
//4 4 4 4 4 4
//4 2 3 3 1 4
//4 2 2 3 1 4
//4 2 3 3 1 4
//4 4 4 4 4 4
//输出
//4
//说明所有4能连起来,还有2 3 1,都有各自能连通块。
//先尝试着用BFS的算法来写,也就是不需要递归,然后需要队列和一个位移数组
//创建一个结构体数组
struct N{
    int x,y,value;
}Node,temp;
int Map[100][100];//创建矩阵数组
int X1[4]={0,0,1,-1};
int Y1[4]={1,-1,0,0};
int n,m;//对应的行列
int i,j;
bool visted[100][100]={false};
//然后需要写一个方法来判断当前位置是否成立
bool judge(int x,int y,int value){
    //分别是行列和当前值,两种情况会返回错误
    //过界
    if(x>=n||y>=m||x<0||y<0)
        return false;
    //被访问过了
    if(visted[x][y]==true)
        return false;
    if(Map[x][y]==value)
        return true;
    return false;//其实完全可以只写第三种情况,其他都返回false
}
void BFS(int x,int y,int value){//开始写BFS
    //创建一个队列
    queue<N> q;
    //然后就是队列的出队入队了
    Node.x=x;
    Node.y=y;
    Node.value=value;
    visted[x][y]=true;//标记为访问过了
    //然后把这个初值入队
    q.push(Node);
    while(!q.empty()){
        //取出队头元素
         Node=q.front();
         q.pop();
         for(i=0;i<4;i++){
              temp.x=Node.x+X1[i];
              temp.y=Node.x+Y1[i];//这个地方别搞错了
              temp.value=Map[temp.x][temp.y];
              //在对这个结点进行判断
              if(judge(temp.x,temp.y,temp.value)){
                //如果可以的话,就入队,并且将其标记为访问过了
                q.push(temp);
                visted[temp.x][temp.y]=true;
              }
    }
}
}
int main()
{
    //先输入行列
    scanf("%d%d",&n,&m);
    //再输入map值
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
        scanf("%d",&Map[i][j]);
    int c=0;//用来统计的,其实就是统计有没有被访问过,因为访问过一个之后,他所有的都会被访问过的
    for(i=0;i<n;i++){
    for(j=0;j<m;j++){
            if(!visted[i][j]){//如果没被访问过,就数值加一,并对其进行深度遍历
                c++;
                BFS(i,j,Map[i][j]);
            }
    }
    }
    printf("%d",c);
}

然后是DFS的

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<queue>
using namespace std;
//给定一个数字矩阵,如果上下左右数值相同,则表示是一个连通的区域。求矩阵中连通块的数量。输入:先是矩阵的行数和列数接着是矩阵输出:连通块的数量
//例子
//5 6
//4 4 4 4 4 4
//4 2 3 3 1 4
//4 2 2 3 1 4
//4 2 3 3 1 4
//4 4 4 4 4 4
//输出
//4
//说明所有4能连起来,还有2 3 1,都有各自能连通块。
//再尝试用DFS写,递归的写
int Map[1000][1000];//创建矩阵数组
int X1[4]={0,0,1,-1};
int Y1[4]={1,-1,0,0};
int n,m;//对应的行列
int i,j;
bool visted[100][100];
//然后需要写一个方法来判断当前位置是否成立
bool judge(int x,int y,int value){
    //分别是行列和当前值,两种情况会返回错误
    //过界
    if(x>=n||y>=m||x<0||y<0)
        return false;
    //被访问过了
    if(visted[x][y]==true)
        return false;
    if(Map[x][y]==value)
        return true;
    return false;//其实完全可以只写第三种情况,其他都返回false
}
void DFS(int x,int y){//先把这个是设置成访问过了
    visted[x][y]=true;
        for(i=0;i<4;i++){
            int newx=x+X1[i];
		int newy=y+Y1[i];
		if(judge(newx,newy,Map[x][y]))
			DFS(newx,newy);
            }
    }

int main()
{
    //先输入行列
    scanf("%d%d",&n,&m);
    //再输入map值
    for(i=0;i<n;i++)
        for(j=0;j<m;j++){
        scanf("%d",&Map[i][j]);
        visted[i][j]=false;
        }
    int c=0;//用来统计的,其实就是统计有没有被访问过,因为访问过一个之后,他所有的都会被访问过的
    for(i=0;i<n;i++){
    for(j=0;j<m;j++){
            if(!visted[i][j]){//如果没被访问过,就数值加一,并对其进行深度遍历
                c++;
                DFS(i,j);
            }
    }
    }
    printf("%d",c);

}


发布了72 篇原创文章 · 获赞 5 · 访问量 2805

猜你喜欢

转载自blog.csdn.net/qq_41115379/article/details/104960948
今日推荐