蓝桥杯第十三届校内赛(第三期)C/C++ 模拟赛赛后反省

起因:前几天参加了第十三届蓝桥杯模拟赛(第三期)C/C++组,特此记录一下,也遇到了一些问题,如果有大佬希望可以在评论区帮忙解决一下,十分感谢!

蓝桥杯第十三届校内赛(第三期)C/C++ 模拟赛赛后反省_第1张图片

目录

第一题

第二题

第三题

第四题

第五题

第六题

第七题

第八题

第九题

第十题


第一题

请问十六进制数 2021ABCD 对应的十进制是多少?

思路:简单的进制转换,算一下就出来了

答案:539077581

第二题

如果一个整数 M 同时是整数 A 和 B 的倍数,则称 M 是 A 和 B 的公倍数,公倍数中最小的一个正整数称为最小公倍数。
  例如:2021 和 86 的最小公倍数是 4042.
  请问在 1(含) 到 2021(含) 中,有多少个数与 2021 的最小公倍数是 4042。

解析:用代码算出来是3

第三题

10 是一个非常特殊的数,它可以表示成两个非负整数的平方和,10 = 3 * 3 + 1 * 1。
  9 也是同样特殊的数,它可以表示成 9 = 3 * 3 + 0 * 0。
  请问,在 1 到 2021 中有多少个这样的数?
  请注意,有的数有多种表示方法,例如 25 = 5 * 5 + 0 * 0 = 3 * 3 + 4 * 4,在算答案时只算一次。

代码:

#include 	
#include
#include

int main(){
    int n;
	//多次输入,方便测试
	while(scanf("%d",&n)!=EOF){
		//满足条件的个数
		int sum = 0;
		//动态创建个数组a
		int *a = (int*)malloc(sizeof(int)*n);
		//全部赋值为0
		memset(a, 0, sizeof(int)*n);
		for (int k = 1; k <= n; k++) {
			for (int i = 0; i <= k; i++) {
				//a[k - 1]=1说明已经找到了满足条件的值,跳出
				if (a[k - 1] != 0) break;
				for (int j = 0; j <= k; j++) {
					if (a[k - 1] != 0) break;
					if (k == (i*i + j * j)) {
						//总数+1
						sum++;
						//输出找到的值,方便查错
						printf("第%d个:  %d = %d*%d + %d*%d\n",sum, k, i, i, j, j);
						//已经找到的标记
						a[k - 1]++;
						break;
					}
				}
			}
		}
		printf("sum=%d\n", sum);
		//将a释放
		free(a);
	}

答案:624

第四题

下面是一个8个结点的无向图的邻接矩阵表示,其中第 i 行第 j 列表示结点 i 到结点 j 的边长度。当长度为 0 时表示不存在边。
  0 9 3 0 0 0 0 9
  9 0 8 1 4 0 0 0
  3 8 0 9 0 0 0 0
  0 1 9 0 3 0 0 5
  0 4 0 3 0 7 0 6
  0 0 0 0 7 0 5 2
  0 0 0 0 0 5 0 4
  9 0 0 5 6 2 4 0
  请问,这个图的最小生成树大小的多少?

思路:用prim算法可以解出来,35

第五题

下面是一个20*20的矩阵,矩阵中的每个数字是一个1到9之间的数字,请注意显示时去除了分隔符号。
  69859241839387868941
  17615876963131759284
  37347348326627483485
  53671256556167864743
  16121686927432329479
  13547413349962773447
  27979945929848824687
  53776983346838791379
  56493421365365717745
  21924379293872611382
  93919353216243561277
  54296144763969257788
  96233972513794732933
  81443494533129939975
  61171882988877593499
  61216868895721348522
  55485345959294726896
  32124963318242554922
  13593647191934272696
  56436895944919899246
  矩阵中一个子矩阵的值是指子矩阵中所有数值的和。
  请问,矩阵中值最大的一个5*5的子矩阵的值是多少?

答案:154

思路:可以写进excel表格里,然后用sum和max函数计算出来154

后面开始就是编程题了

第六题

问题描述

  小蓝要写一个网页显示一些商品。
  商品总共有 t 个,按顺序由 1 到 t 编号,每页显示 a 个,请问第 p 页显示的最小和最大编号是多少?

输入格式

  输入一行包含三个整数 t、a、p,相邻整数之间用一个空格分隔。

输出格式

  输出一行包含两个整数,分别表示最小和最大编号。

样例输入

31 10 3

样例输出

21 30

样例输入

31 10 4

样例输出

31 31

评测用例规模与约定

  对于所有评测用例,1 <= t <= 1000,1 <= a <= 100,1 <= p。保证第 p 页至少显示一个商品

我的代码:

include

int t,a,p,min,max;

int main(){

         scanf("%d %d %d",&t,&a,&p);

    max = a * p;

    if(max >= t){

        max = t;

    }

    min = (a * (p-1)) + 1;

    printf("%d %d",min,max);

    return 0;

}

第七题

问题描述

  给定一个正整数 n,请判断 n 的所有数位上的值是否从左到右是严格递增的。
  例如:1589 是严格递增的。
  再如:1336 不是严格递增的,中间有相同的 3。
  再如:1598 不是严格递增的。

输入格式

  输入一行包含一个整数 n。

输出格式

  如果是严格递增的,输出“YES”(全大写),否则输出“NO”(全大写)。

样例输入

1589

样例输出

YES

样例输入

1336

样例输出

NO

评测用例规模与约定

  对于所有评测用例,1 <= n <= 1000000000。

我的代码:

#include
int main()
{
	char judge[16];
	int f,i,n;
	scanf("%d",&n); //此处输入要判断的数 
	while(n > 0){	//将n逐步放进数组s里 
	    for(int i = 0;i < 11;i++){
	        judge[i] = n % 10;	// 与10求余,得最低位的数字
	        n /= 10;
	    }
	}
	//逐步判断 
	for(f = 1,i = 1;judge[i];i++){
		//因为我先将最低位放在第一位,所以需要判断第一位是否大于第二位
		if(judge[i] > judge[i - 1]){	 
			f=0;
			break;
		}
	}
	puts((f ? "Yes" : "No"));
	return 0;
}

第八题

问题描述

  小蓝将自己的车停在路边,在同一天将车开走。给定停车时间和开走时间,请问小蓝停了多长时间?

输入格式

  输入两行,第一行包含停车时间,第二行包含开走时间。
  每个时间的格式为 HH:MM:SS,其中 HH 表示时,值为 0 到 23 的整数,如果小于 10 用 0 补齐两位;MM 和 SS 分别表示分和秒,值为 0 到 59 的整数,小于 10 时用 0 补齐两位。

输出格式

  输出总共停车的时间,格式为 HH:MM:SS。

样例输入

08:58:10
17:20:31

样例输出

08:22:21

我的代码:

#include

int main(){

    int starthh,startmm,startss,stophh,stopmm,stopss,finalhh,finalmm,finalss;

         scanf("%d:%d:%d",&starthh,&startmm,&startss);

         scanf("%d:%d:%d",&stophh,&stopmm,&stopss);

         finalhh = stophh - starthh;

         finalmm = stopmm - startmm;

         finalss = stopss - startss;

         if(finalhh < 0){

                   printf("开走时间早于停车时间,时间错误");

         }

         if(finalmm < 0){

                   finalhh--;

                   finalmm = stopmm + 60 - startmm;

         }

         if(finalss < 0){

                   finalmm--;

                   finalss = stopss + 60 - startss;

         }

         printf("%02d:%02d:%02d\n",finalhh,finalmm,finalss);//按规定格式输出时分秒

         return 0;

}

第九题

问题描述

  n 个运动员参加一个由 m 项运动组成的运动会,要求每个运动员参加每个项目。
  每个运动员在每个项目都有一个成绩,成绩越大排名越靠前。每个项目,不同运功员的成绩不会相同,因此排名不会相同。(但是不同项目可能成绩会相同)
  每个项目的前 k 名分别获得 k 到 1 分,第 i 名获得 max(k+1-i, 0) 分。
  每个运动员的总分就是他在每个项目上获得的分数之和。
  请计算每个运动员的总分。

输入格式

  输入的第一行包含两个整数 n, m, k,用一个空格分隔。
  接下来 n 行,每行包含 m 个整数,第 i 行第 j 个整数表示第 i 个运动员在第 j 项比赛的成绩。

输出格式

  输出一行包含 n 个整数,依次表示每个运动员的总分,相邻的整数之间用一个空格分隔。

样例输入

3 5 2
5 3 1 5 12
2 4 2 34 1
8 6 3 2 2

样例输出

4 4 7

样例说明

  第 1 个运动员得分为:1+0+0+1+2=4
  第 2 个运动员得分为:0+1+1+2+0=4
  第 3 个运动员得分为:2+2+2+0+1=7

评测用例规模与约定

  对于 50% 的评测用例,2 <= n, m, k <= 20,0 <= 成绩 <= 1000。
  对于所有评测用例,2 <= n, m, k <= 100,0 <= 成绩 <= 10000。

代码:

#include 
#include 
#include 
using namespace std;

vector grade[10005];
int goal[10005][10005];
int n, m, k;
int a[10005];

int reset(int i, int j) //返回下标 ,也是就名次
{
    int x = goal[i][j];
    for (int z = 0; z < n; z++)
    {
        if (a[z] == x)
            return z;
    }
}
bool comp(int a, int b)
{
    return a > b;
}
int main()
{
    cin >> n >> m >> k;
    for (int i = 0; i < n; i++) //代表运动员
    {
        for (int j = 0; j < m; j++)
        {
            cin >> goal[i][j];
        }
    }
    for (int j = 0; j < m; j++) //项目
    {
        for (int i = 0; i < n; i++)
        {
            a[i] = goal[i][j]; //每个运动员项目的分数
        }
        sort(a, a + n, comp);       //排序
        for (int i = 0; i < n; i++) //给,每个运动员分数
        {
            int u = reset(i, j);
            int y = max(k - u, 0);
            grade[i].push_back(y);
        }
    }
    int sum[10005];
    for (int i = 0; i < n; i++) //代表运动员
    {
        for (int j = 0; j < m; j++)
        {
            sum[i] += grade[i][j];
        }
    }
    for (int i = 0; i < n; i++)
        cout << sum[i] << " ";
}

第十题

问题描述

  给定 n 个整数 a[1], a[2], ..., a[n],小蓝希望在中间选出一部分,满足以下两个条件:
  1. 对于某个下标集合 S,选出的数中有至少 k 个下标在集合 S 中;
  2. 选出的数按照原来的顺序排列,是严格单调上升的,即选出的是一个上升子序列。
  请问小蓝最多能选出多少个数。

输入格式

  输入的第一行包含两个整数 n, k,用一个空格分隔。
  第二行包含 n 个整数 a[1], a[2], ..., a[n],相邻的整数间用空格分隔。
  第三行包含一个长度为 n 的01串,依次表示每个下标是否在集合 S 中,为 0 表示不在 S 中,为 1 表示在 S 中。

输出格式

  输出一行包含一个整数,表示答案。如果没有满足条件的选法,输出-1。

样例输入

8 2
8 1 2 3 9 4 7 10
10001010

样例输出

3

样例说明

  由于 8、9、7 三个数中至少要选 2 个,只能选 8 和 9,剩下的数只能选最后一个数 10。

样例输入

8 3
8 1 2 3 9 4 7 10
10001010

样例输出

-1

评测用例规模与约定

  对于 30% 的评测用例,2 <= n <= 100,0 <= a[i] <= 100, 0 <= k <= 3。
  对于所有评测用例,2 <= n <= 1000,0 <= a[i] <= 100000, 0 <= k <= 20。

思路:没写出来,有大佬写出来在评论区告诉一下我

反省:总体来说蓝桥杯校内赛难度并不大,还交了30块报名费,大多数编程题都是可以暴力直接解决,不需要太多关于算法的技巧,前面的填空题需要一些DS的基础,例如树,图什么的都要学到。我个人基础还是不够牢固。如果想参加蓝桥杯的话,可以去力扣或者牛客网刷一下题再参加,适应一下难度,多刷题,坚持,努力,上进。

你可能感兴趣的:(C语言,蓝桥杯,模拟赛,蓝桥杯,职场和发展,C语言,算法,c++)