基础题

1-1 无所谓,我会出手

请直接输出 :“It doesn’t matter,I’ll do it.”(输出不含引号)。

  • 直接输出即可。
    int main()
    {
        printf("It doesn't matter,I'll do it.");
        return 0;
    }

1-2 数组总和

给出一个正整数 n 和一段长度为n的数组a1,a2…an ,请输出1×a1+2×a2+3×a3+4×a 4​+…+n×an的结果。

输入格式
第一行为 整数 n(1<=n<=1e3)
第二行为n 个整数 ai(1<=ai<=1e9)

输出格式
输出一行一个正整数,代表题目要求的值。

样例输入
4
1 2 3 4
样例输出
30

  • 使用for循环,初始化i=1,每次相乘后储存到sum里。注意sum需要long long类型,避免爆int。
    int main()
    {
        int n,i;
        long long sum=0,x;
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%lld",&x);
            sum+=x*i;
        }
        printf("%lld",sum);
        return 0;
    }

1-3 捡到一个矩形

这天,我捡到了一个二维坐标轴,坐标轴上有一个矩形,现在给出一个点的坐标,问这个坐标是否在矩形中。

输入格式
输入第一行一个整数t,代表测试组数 (1<=t<=10)
接下来2×t行,每组测试用例第一行为四个整数,分别为正方形的左下角的坐标x1,y1和矩形的右上角 x2,y2
第二行为询问的点的坐标 x,y(−1e9<=x,y,x1,x2,y1,y2<=1e9)

输出格式
如果在矩形中或者在矩形的边界上,输出 YES;否则输出 NO。

样例输入
2
0 0 2 2
1 1
1 1 2 2
0 0
样例输出
YES
NO

  • 坐标在给出的范围之内即可。
    int main()
    {
        int n,i,x1,x2,y1,y2,x,y;
        scanf("%d",&n);
        for(i=0;i<n;i++){
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            scanf("%d%d",&x,&y);
            if(x>=x1&&x<=x2&&y>=y1&&y<=y2)
                printf("YES\n");
            else
                printf("NO\n");
        }
        return 0;
    }

1-4 字符转换

现给你一种对字符的操作,使其变成该字符在字母表后的第x个位置,x为该字符在字母表中的位置。例如,对字符a进行操作,会将其变成a后的第一个字母,即b;对字符b进行操作,会将其变成b后的第二个字母,即d….以此类推。需要注意的是,该字母表是一个循环字母表,即字符z后的第一个字符是a,a后又是b,循环往复。现在给你一个字符串s,s 均由小写字母组成,1<=∣s∣<=1e5,请输出对字符串s的每一位字符进行操作后的结果。

输入格式
一行输入一个字符串s,含义如题面所示

输出格式
输出一行一个字符串,代表对s每一位字符进行操作后的结果。

样例输入
upupup
样例输出
pfpfpf

  • 难点是对循环的处理,我的处理方法是通过判断26个字母的中间作为是否循环的标志
    int main()
    {
        char arr[100005];
        scanf("%s",arr);
        for(int i=0;arr[i]!='\0';i++){
            if(arr[i]-'a'+1>13)
                arr[i]-=25-arr[i]+'a';    //等同于26-(arr[i]-'a'+1)
            else
            arr[i]+=arr[i]-'a'+1;
        }
        for(int i=0;arr[i]!='\0';i++){
            printf("%c",arr[i]);
        }
        return 0;
    }

1-5 捡到了一个成绩

天梯赛过后,所有同学的成绩被打印在一张纸上。现在老师想要统计某班得分的均值,以及得分高于这个均值的同学们的分数之和,请你帮助老师计算出这两个值。

输入格式
第一行输入一个正整数n,代表该班级的人数。(1<=n<=30)
第二行输入n个整数,代表第i名同学的得分x。(0<=x<=290)

输出格式
输出两行,第一行输出一个实数,代表得分的均值。(保留到小数点后三位)
第二行输出一个整数,代表得分高于该班级分数均值的同学们的分数之和。

样例输入
6
13 105 237 173 273 134
样例输出
155.833
683

  • 简单题,注意整型要*1.0
    int main()
    {
        int n,sum=0,sum2=0,arr[10000];
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&arr[i]);
            sum+=arr[i];
        }
        double aver=sum*1.0/n;
        for(int i=0;i<n;i++){
            if(arr[i]*1.0>aver)
                sum2+=arr[i];
        }
        printf("%.3lf\n%d",aver,sum2);
        return 0;
    }

1-6 炎爆

cys学姐非常喜欢Arknights这款游戏,而其中伊芙利特是她最引以为傲的干员之一。给你一个n×n的矩形a,矩形中的每一个位置都有一个敌人,其中a[x][y]代表矩形第x行,第y列上的敌人。假设伊芙利特部署在(x,y)的位置上,并且朝向右,那么伊芙利特会对(x,y),(x,y+1),(x,y+2)….(x,n)的所有敌人造成1点伤害。现在给你q次部署,每次部署都给出一个部署位置(x,y),代表伊芙利特部署在矩形的第x行,第y列,再给出一个字符op,代表伊芙利特的朝向(U代表向上,R代表向右,D代表向下,L代表向左)。你能精确算出每个敌人受到的伤害吗?

输入格式
第一行一个正整数n,代表矩形的大小(1<=n<=100),初始情况下所有敌人受到的伤害为0。
第二行给出一个正整数q,代表伊芙利特的部署次数(1<=q<=50)。
接下来q行,每行给定一个数对(x,y),1<=x,y<=n,代表伊芙利特的部署位置,和一个字符op,op∈{U,R,D,L},代表伊芙利特的朝向。

输出格式
输出n行,每行n个整数,分别对应矩阵a中每个敌人受到的伤害。

样例输入
5
3
2 2 R
4 3 U
5 5 L
样例输出
0 0 1 0 0
0 1 2 1 1
0 0 1 0 0
0 0 1 0 0
1 1 1 1 1
题目图片

  • 使用for循环控制好变量处理即可,不难但有点麻烦。
    注意行末空格的处理!
    int main()
    {
        int n,x,numx,numy;
        char dire;
        scanf("%d",&n);
        int arr[n+1][n+1];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                arr[i][j]=0;
            }
        }
        scanf("%d",&x);
        for(int i=0;i<x;i++){
            scanf("%d%d %c",&numx,&numy,&dire);
            if(dire=='U'){
                for(int z=0,j=0;j<numx;j++,z++){
                    arr[numx-1-z][numy-1]++;
                }
            }
            else if(dire=='R'){
                for(int z=0,j=0;j<n-numy+1;j++,z++){
                    arr[numx-1][numy-1+z]++;
                }
            }
            else if(dire=='D'){
                for(int z=0,j=0;j<n-numx+1;j++,z++){
                    arr[numx-1+z][numy-1]++;
                }
            }
            else if(dire=='L'){
                for(int z=0,j=0;j<numy;j++,z++){
                    arr[numx-1][numy-1-z]++;
                }
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(j==0)
                    printf("%d",arr[i][j]);
                else
                printf(" %d",arr[i][j]);
                if(j==n-1)
                    printf("\n");
            }
        }
        return 0;
    }

1-7 攻略迷宫

小A准备挑战一个副本,他的角色拥有 x 点生命值,boss 每第 y 秒攻击一次,每次对角色造成1点伤害,当角色生命值为零时游戏结束,不会再受到攻击。现在给你一个时间段,假如小A从这个时间段开始时着手攻略副本,小A想知道他的角色在这段时间内会承受多少次攻击,以及最后一次被攻击的时间。

输入格式
第一行两个整数 x 和 y(1<=x,y<=100) ,由空格隔开。
下面两行两个时间,格式为XX:XX:XX ,代表给定的时间段的开始和结束时间。
数据保证时间合法,且开始时间和结束时间在同一天

输出格式
输出共两行:
第一行为小A的角色承受boss攻击的次数
第二行一个时间,代表小A的角色最后一次遭受攻击的时间,格式为XX:XX:XX

样例输入
5 60
18:00:00
18:04:30
样例输出
4
18:04:00
样例说明
如样例,boss 每第 60 秒攻击一次,角色第一次受到攻击时 18:01:00,最后一次是18:04:00 。共承受 4 次攻击。

  • 时分秒的计算繁琐且十分容易错,我们可以全部转换为秒再进行计算
    int miao(int t11,int t22,int t33)    //转换为秒
    {
        int miaouu=t33+t22*60+t11*3600;
        return miaouu;
    }
    
    void biao(int ress)   //转换为标准格式
    {
        int h=0,m=0,s=0;
        while(ress>=3600){
             h++;
             ress-=3600;
        }
        while(ress>=60){
             m++;
             ress-=60;
        }
            s=ress;
        printf("%02d:%02d:%02d",h,m,s);
    }
    
    int main()
    {
        int x,y,t1,t2,t3,tt1,tt2,tt3,time1,time2,num=0;
        scanf("%d%d",&x,&y);
        scanf("%d:%d:%d",&t1,&t2,&t3);
        scanf("%d:%d:%d",&tt1,&tt2,&tt3);
        time1=miao(t1,t2,t3);
        time2=miao(tt1,tt2,tt3);
        int time=time2-time1;
        while(time>=y&&x>0){
            num++;
            time-=y;
            time1+=y;
            x--;
        }
        printf("%d\n",num);
        biao(time1);
        return 0;
    }

1-8 去掉重复的数据

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,去掉所有重复的数字。最后按照输入顺序输出没有重复数字的数据。所有重复的数字只保留第一次出现的那份。

输入格式:
你的程序首先会读到一个正整数 n,1≤n≤100000。
然后是 n 个整数,这些整数的范围是 [1, 100000]。

输出格式:
在一行中按照输入顺序输出去除重复之后的数据。每两个数据之间有一个空格,行首尾不得有多余空格。

输入样例:
5
1 2 2 1 4
输出样例:
1 2 4

  • 题目中数据不大,可以开一个数组,输出答案后,变动数组的值,使其不再输出
    同样注意空格问题!
    int main()
    {
        int n,x,arr[100005]={0},num=1;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&x);
            if(arr[x]==0&&num){
                printf("%d",x);
                num=0;
            }
            else if(arr[x]==0){
                printf(" %d",x);
            }
            arr[x]++;
    }
    return 0;
    }

进阶题

2-1 聚餐

有一个班有 n 个人, 从 1∼n 编号。这学期班里一共举行了 m 次聚餐,第i 次聚餐有 k i​个人参加。如果两名同学参加过同一场聚餐,那么我们就说这两个同学是熟悉的。现在给你q次询问,每个询问包含两个同学的编号a、b,问同学a和同学b是否熟悉。

输入格式
第一行三个整数n,m,q(1<=n,m,q<=100)。分别代表同学人数,聚餐次数和询问次数。
接下来m行,每行第一个数 ki代表这次聚餐的人数,后面是 k i个同学的编号。
接下来 q行,每行两个整数 x和 y代表两个同学的编号。(x!=y)

输出格式
输出包含 q行,每行对应一个询问的答案,如果同学a和同学b是熟悉的,输出 YES;否则输出 NO 。

样例输入
3 2 2
2 1 2
2 1 3
1 2
2 3
样例输出
YES
NO
提示
样例中,共有3名学生,2场聚餐,2次询问
第一次聚餐有2名同学参加,分别是同学1和同学2
第二次聚餐有2名同学参加,分别是同学2和同学3
第一次询问,同学1和同学2都参加过第一场聚餐,所以输出YES
第二次询问,同学2和同学3没有参加过同一场聚餐,所以输出NO

  • 每次输入记录在arr里,同时使二维数组brr[arr[num1]][arr[num2]]和brr[arr[num2]][arr[num1]]的方式记录和判断两位同学是否熟悉
    int main()
    {
        int n,m,q,num1,num2,num3;
        int arr[105],brr[105][105];
        scanf("%d%d%d",&n,&m,&q);
        while(m--){
            scanf("%d",&num1);
            for(int i=1;i<=num1;i++){
                scanf("%d",&arr[i]);
            }
            for(int i=1;i<=num1;i++){
                for(int j=i+1;j<=num1;j++){
                    brr[arr[i]][arr[j]]=brr[arr[j]][arr[i]]=1;
                }
            }
        }
            while(q--){
                scanf("%d%d",&num2,&num3);
                puts(brr[num2][num3]?"YES":"NO");
            }
        return 0;
    }

2-2 捡到两个字符串

小孤独总是喜欢低着头走路,因此经常捡到奇怪的东西,这天她捡到了两只字符串。给出两个由小写字母组成的字符串,一个整数m,以及m个由26个不同的小写字母构成的字符串作代表的新字母表,字符大小关系是按照顺序从小到大。请按照新的字母表以字典序的比较方法来比较,输出较小的字符串,若相同输出任意一个。字典序比较的解释:一个字符串小于另一个字符串,当且仅当以下情况之一成立
1.a是b的前缀,且a!=b。
2.在a和b不同的第一个位置,字符串a有一个字母在字母表中出现的时间比b中的相应字母早。
例如:按照正常的字母表abcdefghijklmnopqrstuvwxyz字符大小从小到大来比较,abc<bcd , aa<aaa , aab>aaa。

输入格式
前两行分别为两个字符串s1,s2(1<=∣s∣<=10000)
第三行为一个整数 m,代表给出m个新的字母表。(1<=m<=100)
接下来m行为m个字母表。

输出格式
对于每一个字母表输出相对应的较小的字符串。

样例输入
aaa
aab
2
abcdefghijklmnopqrstuvwxyz
bacdefghijklmnopqrstuvwxyz
样例输出
aaa
aab

补充
对于前10组测试用例,保证m=1且给定字母表为abcdefghijklmnopqrstuvwxyz,因此你只需要按照正常字典序进行比较

  • 本题使用映射的方法解决,将新的规则一个一个字符的转化为数字储存
    int main()
    {
        int n,flag=0,ys[200];//ys=映射
        char arr[1000005],brr[1000005],neww[27];//neww=新规则
        scanf("%s",arr);
        scanf("%s",brr);
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%s",neww);
            for(int j=0;neww[j];j++){
                ys[neww[j]]=j;  //映射与数字顺序对应
            }
            for(int i=0;arr[i]&&brr[i];i++){
                if(ys[arr[i]]<ys[brr[i]]){
                    flag=1;
                    break;
                }
                else if(ys[arr[i]]>ys[brr[i]]){
                    flag=2;
                    break;
                }
            }
                if(flag==1)
                    printf("%s\n",arr);
                else if(flag==2)
                    printf("%s\n",brr);
                else{
                    if(strlen(arr)<strlen(brr))
                        printf("%s\n",arr);
                    else
                        printf("%s\n",brr);
                }
            }
        return 0;
    }

2-3 打印菱形 (Hard-ver)

给定一个 n ,代表菱形的边长,请输出要求大小的图形(详见样例)。

输入格式
输入一行一个整数 n(2<=n<=100) ,代表菱形的边长(数据保证n为偶数)。

输出格式
输出见样例:

样例输入
样例输出
题目图片

  • 热知识:输出“\”需要“\”
    int main(){
    int n;scanf("%d",&n);
    
    // 上半未重合部分
    for(int i=1;i<=n/2;i++){
    
    for(int j=1;j<=n-i;j++)
        printf(" ");
    printf("/");
    for(int j = 1;j<=2*(i-1);j++)
        printf(" ");
    printf("\\");
    for(int j = 1;j<=n-(i*2-1);j++)
        printf(" ");
    printf("/");
    for(int j = 1;j<=2*(i-1);j++)
        printf(" ");
    printf("\\");
    puts("");
    }
    
    // 上半重合部分
    for(int i=n/2+1;i<=n;i++){
    
    for(int j=1;j<= n-i;j++)printf(" ");
        printf("/");
    for(int j=1;j<=n;j++)printf(" ");
        printf("/");
    for(int j=1;j<=2*(i-1);j++)printf(" ");
        printf("\\");
    puts("");
    }
    
    //下半重合部分
    for(int i=1;i<=n/2;i++){
    
    for(int j=1;j<=i-1; j++)printf(" ");
        printf("\\");
    for(int j = 1;j<=n;j++)printf(" ");
        printf("\\");
    for(int j=1;j<=2*(n-i);j++) printf(" ");
        printf("/");
    puts("");
    }
    
    //下半未重合部分
    for (int i=n/2+1;i<=n;i++){
    
    for (int j=1;j<= i-1;j ++ )printf(" ");
        printf("\\");
    for (int j=1;j<=2*(n-i);j++)printf(" ");
        printf("/");
    for (int j=1;j<=n-(2*(n-i)+1);j++)printf(" ");
        printf("\\");
    for (int j=1;j<=2*(n-i);j++)printf(" ");
        printf("/");
    puts("");
    }
    return 0;
    }

最后四题就不做总结了,为什么捏?大家看看提交率和通过率就知道了。。。
题目图片