问题描述:
请找到一个大于 2022 的最小数,这个数转换成十六进制之后,所有的数位(不含前导 0)都为字母(A 到 F)。
请将这个数的十进制形式作为答案提交。
//1.最小数
int main()
{
int i = 2023;
for ( i = 2023; i; i++)//for循环中不写第二个条件即没有限制条件,此循环可以一直进行
{
int sum = i;//定义一个sum来进行判断,如果最小数则直接返回i(因为sum已经被改变)
char ch = 0;//定义一个字符,讲每个除下来的数进行字符转换去比较
while(sum!=0)
{
ch = sum % 16+'0';//因为除下来的数为整形所以要加‘0’进行字符类型转换
if (ch<='9')//因为16进制最小的字母为a,整形数字为10,所以要判断每次除下来数的是否<=9。
{
break;//若<=9则直接终止此次循环进行下一次的for循环。
}
else
{
sum /= 16;//因为为16进制判断所以每次要除16。
}
}
//当每次除下来的数(每位数)都大于9时说明这个数符合题目要求,且此时sum已经为0;
if (sum==0)
{
break;//这里我们再来判断sum是否已经为0,若为0则直接跳出for循环。
}
}
printf("%d\n", i);//因为我们把i赋值给了sum再来判断,i保留了真正的答案所以打印i;
return 0;
}
答案2730
第二题,填空题
问题描述
在 Excel 中,列的名称使用英文字母的组合。前 26 列用一个字母,依次为 A 到 Z,接下来 26*26 列使用两个字母的组合,依次为 AA 到 ZZ。
请问第 2022 列的名称是什么?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个由大写字母组成的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。
//2.求列名
//这道题可以看作把十进制2022转换为26进制来代表(按题中意思,26进制1-26用A-Z来表示)
int main()
{
//我们来定义一个数组来保存每次2022%26的余数最后再来转换成26进制符号(题中A-Z)来表示;
int arr[4] = { 0 };//这里我们把数组大小定义小点,因为26进制转换成10进制的数很大,4个空间足矣。
int sum = 2022;
int i = 0;
while (sum)
{
arr[i++] = sum % 26;//用来保存余数,存放完后我们i++方便下一个数组空间存放新的余数。
sum /= 26;
}
for(int j=i-1;j>=0;j--)//依据十进制与二进制的转换是从后向前排序,所以我们先把i-1赋值给j先改变最后一个余数。不理解的可以举个十进制转换成二进制,依次除2后倒着排序。
{ //我们把余数赋值后立马i++,意为我们先找到下一个数组空间再赋值,但是最后的时候sum/26=0了无法再进入while循环,但是我们i已经在上次循环多加了一次,所以要i-1
printf("%c",'A' + arr[j] - 1);//为什么arr[j]-1,举例子我们第一个余数为20转换成26进制符号为 T 但是A加20为U多加了一次所以要减一。
//为什么不能直接‘0‘+arr[j]-1,因为我们转换为字母所以要根据ascii码来大写字母从A(十进制:97)开始不能直接把20转换为对应的ASCII码
//所以要先用A加再减1.
}
return 0;
}
答案:BYT
3.求日期数
问题描述:
对于一个日期,我们可以计算出年份的各个数位上的数字之和,也可以分别计算月和日的各位数字之和。请问从 1900 年 1 月 1 日至 9999 年 12 月 31 日,总共有多少天,年份的数位数字之和等于月的数位数字之和加日的数位数字之和。例如,2022年11月13日满足要求,因为 2+0+2+2=(1+1)+(1+3) 。
请提交满足条件的日期的总数量。
//3.求日期数
//求各为数的和函数
int just(int x)//判断是否为闰年的函数,如果是闰年则返回1
{
if (x % 400 == 0 || (x % 4 == 0&&x%100!=0))
{
return 1;
}
else
{
return 0;
}
}
int add(int y)//我们定义一个函数用来求年 月 日,各位上的数字相加之和。
{
int sum = 0;
while (y)
{
sum += y % 10;
y /= 10;
}
return sum;
}
int main()
{
int month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31};//定义一个数组,让每个月月份对应其坐标,数组内容为对应月的天数。
int i = 0;
int count = 0;//用来统计符号条件的日期次数
for (i = 1900; i <10000; i++)
{
//把年份传参给函数just如果是闰年则二月为29天否则为28天
if (just(i))
{
month[2] = 29;
}
else
{
month[2] = 28;
}
int yearAdd = add(i);//我们i也就是年份传参到函数add用来计算年各位相加之和
int j = 0;
for (j = 1; j < 13; j++)//月循环
{
int k = 0;
for (k = 1; k <= month[j]; k++)//每月对应有几天(month[j])来循环
{
int m_dAdd = add(j) + add(k);
if (yearAdd == m_dAdd)//如果年各位数相加和等于日与月各位数相加和则count++
{
count++;
}
}
}
}
printf("%d\n", count);//最后输出符合条件日期的总个数。
return 0;
}
答案:70910
4.取数
问题描述:
小蓝有 30 个数,分别为:99, 22, 51, 63, 72, 61, 20, 88, 40, 21, 63, 30, 11, 18, 99, 12, 93, 16, 7, 53, 64, 9, 28, 84, 34, 96, 52, 82, 51, 77 。
小蓝可以在这些数中取出两个序号不同的数,共有 30*29/2=435 种取法。
请问这 435 种取法中,有多少种取法取出的两个数的乘积大于等于 2022 。
//4.取数
int main()
{
int count = 0;
int arr[30] = { 99, 22, 51, 63, 72, 61, 20, 88, 40, 21, 63, 30, 11, 18, 99, 12, 93, 16, 7, 53, 64, 9, 28, 84, 34, 96, 52, 82, 51, 77 };
for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)//先循环第一次,每个数都循环一变
{
for ( int j = i+1; j =2022)
{
count++;
}
}
}
printf("%d\n", count);
return 0;
}
答案189
5.最大连通分块
(本题为dfs算法目前博主还没有涉及)可参考:https://blog.csdn.net/m0_74183164/article/details/129453651
问题描述:
小蓝有一个 30 行 60 列的数字矩阵,矩阵中的每个数都是 0 或 1 。
如果从一个标为 1 的位置可以通过上下左右走到另一个标为 1 的位置,则称两个位置连通。与某一个标为 1 的位置连通的所有位置(包括自己)组成一个连通分块。
请问矩阵中最大的连通分块有多大?
6.n天后周几
输入格式
输入第一行包含一个整数 w,表示给定的天是一周中的哪天,w 为 1 到 6 分别表示周一到周六,w 为 7 表示周日。第二行包含一个整数 n。
输出格式
输出一行包含一个整数,表示 n 天后是一周中的哪天,1 到 6 分别表示周一到周六,7 表示周日。。
评测用例规模与约定
对于所有评测用例,1 <= n <= 1000000。
//6.顺还队列的思想
int main()
{
int day = 0;
printf("请输入周几:>\n");
scanf_s("%d", &day);
int n = 0;
printf("请输入往后的天数:>\n");
scanf_s("%d", &n);
int ret = (day + n) % 7;
if (ret==0)
{
ret += 1;
}
printf("%d\n", ret);
return 0;
}
样例输入
6
10
样例输出
2
7.信号塔信号覆盖点数
问题描述
小蓝负责一块区域的信号塔安装,整块区域是一个长方形区域,建立坐标轴后,西南角坐标为 (0, 0), 东南角坐标为 (W, 0), 西北角坐标为 (0, H), 东北角坐标为 (W, H)。其中 W, H 都是整数。
他在 n 个位置设置了信号塔,每个信号塔可以覆盖以自己为圆心,半径为 R 的圆形(包括边缘)。
为了对信号覆盖的情况进行检查,小蓝打算在区域内的所有横纵坐标为整数的点进行测试,检查信号状态。其中横坐标范围为 0 到 W,纵坐标范围为 0 到 H,总共测试 (W+1) * (H+1) 个点。
给定信号塔的位置,请问这 (W+1)*(H+1) 个点中有多少个点被信号覆盖。
输入格式
输入第一行包含四个整数 W, H, n, R,相邻整数之间使用一个空格分隔。
接下来 n 行,每行包含两个整数 x, y,表示一个信号塔的坐标。信号塔可能重合,表示两个信号发射器装在了同一个位置。
输出格式
输出一行包含一个整数,表示答案。
评测用例规模与约定 对于所有评测用例,1 <= n <= 100,每个单词的长度不超过 100。
//7.信号塔信号覆盖点数
int main()
{
int W = 0;//x轴
int H = 0;//y轴
int n = 0;//需要放置信号的次数
int R = 0;//半径
int arr[101][101];//定义最大的坐标系xy坐标
int i = 0;
int j = 0;
int count = 0;//用来统计被覆盖点的个数
scanf_s("%d %d %d %d", &W, &H, &n, &R);
int x = 0;
int y = 0;//定义x,y即我们要放置信号的坐标
while (n--)//防止n个每一次放置先进行排查所以为n--
{
scanf_s("%d %d", &x, &y);//输入放置信号的坐标
arr[x][y] = 1;
for (i = 0; i <=W; i++)//x轴每次循环
{
for (j = 0; j <=H; j++)//y轴每次循环
{
if ((i - x) * (i - x) + (j - y) * (j - y) <= pow(R, 2))//这里我们运用了高中知识,即每次测试的坐标与xy比看两点之间的距离是否小于等于R如果<=说明被覆盖
{ //两点之间距离:(x1-x2)^2+(y1-y2)^2 {
arr[i][j] = 1;//我们把每次被覆盖(与xy距离小于等于半径)的点赋值为1.
}
}
}
}
for ( i = 0; i <= W; i++)
{
for ( j = 0; j <= H; j++)
{
if (arr[i][j] == 1)//这样我们用count统计,输出所有点,若被赋值为1则count++
count++;
}
}
printf("%d\n", count);
return 0;
}
样例输入
10 10 2 5
0 0
7 0
样例输出
57
8.清理水草
问题描述
小蓝有一个 n * m 大小的矩形水域,小蓝将这个水域划分为 n 行 m 列,行数从 1 到 n 标号,列数从 1 到 m 标号。每行和每列的宽度都是单位 1 。
现在,这个水域长满了水草,小蓝要清理水草。
每次,小蓝可以清理一块矩形的区域,从第 r1 行(含)到第 r2 行(含)的第 c1 列(含)到 c2 列(含)。
经过一段时间清理后,请问还有多少地方没有被清理过。
输入格式
输入第一行包含两个整数 n, m,用一个空格分隔。
第二行包含一个整数 t ,表示清理的次数。
接下来 t 行,每行四个整数 r1, c1, r2, c2,相邻整数之间用一个空格分隔,表示一次清理。请注意输入的顺序。
输出格式
输出一行包含一个整数,表示没有被清理过的面积。
评测用例规模与约定
对于所有评测用例,1 <= r1 <= r2 <= n <= 100, 1 <= c1 <= c2 <= m <= 100, 0 <= t <= 100。
//8.清理水草
int main()
{
int arr[100][100] = {100};//我们定义一个二维数组假设为n m的最大值
int n = 0;
int m = 0;
scanf_s("%d %d", &n, &m);//先输入n m的值也就是矩形水域的长和宽
int t = 0;
scanf_s("%d",&t);//输入要清理的次数
int x1 = 0, y1 = 0;
int x2 = 0, y2 = 0;
int i = 0;
int j = 0;
int count = 0;
while (t--)
{
scanf_s("%d %d %d %d", &x1, &y1, &x2, &y2);//输入每次清理从第x1行的第y1列到x2行的y2列
for (i = x1-1; i <= x2-1; i++)//这里for循环中的x y都要-1,因为在数组中起始坐标为0,而我们生活中是以1开头的
{ //如我们想清理(1,1)也就是第一行第一列,而在数组中的表示为(0,0).
for ( j = y1-1; j <=y2-1; j++)
{
arr[i][j] = 1;//我们把已经清理的面积赋值为1.
}
}
}
//把所有的数组(水域面积)都遍历一边,如果不等于1则是我们没有清理的水域,用count统计。
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if (arr[i][j] != 1)
{
count++;//我们用count来统计没有清理过的水域,每日记录一个count++
}
}
}
printf("%d ", count);//最后我们输入count的值也就是没有清理的面积
return 0;
}
样例输入
2 3
2
1 1 1 3
1 2 2 2
样例输出
2
样例输入
30 20
2
5 5 10 15
6 7 15 9
样例输出
519
9.滑行距离
(此题也为dfs法可参考第五题链接)
问题描述
小蓝准备在一个空旷的场地里面滑行,这个场地的高度不一,小蓝用一个 n 行 m 列的矩阵来表示场地,矩阵中的数值表示场地的高度。
如果小蓝在某个位置,而他上、下、左、右中有一个位置的高度(严格)低于当前的高度,小蓝就可以滑过去,滑动距离为 1 。
如果小蓝在某个位置,而他上、下、左、右中所有位置的高度都大于等于当前的高度,小蓝的滑行就结束了。
小蓝不能滑出矩阵所表示的场地。
小蓝可以任意选择一个位置开始滑行,请问小蓝最多能滑行多远距离。
输入格式
输入第一行包含两个整数 n, m,用一个空格分隔。
接下来 n 行,每行包含 m 个整数,相邻整数之间用一个空格分隔,依次表示每个位置的高度。
输出格式
输出一行包含一个整数,表示答案。
评测用例规模与约定
对于 30% 评测用例,1 <= n <= 20,1 <= m <= 20,0 <= 高度 <= 100。
对于所有评测用例,1 <= n <= 100,1 <= m <= 100,0 <= 高度 <= 10000。
10.求最小值
问题描述
小蓝有一个序列 a[1], a[2], …, a[n]。
给定一个正整数 k,请问对于每一个 1 到 n 之间的序号 i,a[i-k], a[i-k+1], …, a[i+k] 这 2k+1 个数中的最小值是多少?当某个下标超过 1 到 n 的范围时,数不存在,求最小值时只取存在的那些值。
输入格式
输入的第一行包含一整数 n。
第二行包含 n 个整数,分别表示 a[1], a[2], …, a[n]。
第三行包含一个整数 k 。
输出格式
输出一行,包含 n 个整数,分别表示对于每个序号求得的最小值。
评测用例规模与约定
对于 30% 的评测用例,1 <= n <= 1000,1 <= a[i] <= 1000。
对于 50% 的评测用例,1 <= n <= 10000,1 <= a[i] <= 10000。
对于所有评测用例,1 <= n <= 1000000,1 <= a[i] <=1000000。
//10.求最小值
#define MAX_SIZE 1000001//我们先宏定义一个最大数来代替我们数组的空间。
long long arr[MAX_SIZE] = { 0 };//数组空间过大时要开在上面,防止爆 。
//因题目要求数字最大值过大所以我们用long long类型
int main()
{
long long n=0;
long long min = 0;
scanf_s("%lld", &n);//先输入数子的个数。
for (int i=1; i<=n; i++)//进行循环,挨个输入每个数字共n个。
{
scanf_s("%lld",&arr[i]);
}
long long k = 0;
scanf_s("%lld",&k);//输入整数k。
for (int i=1; i<=n; i++)
{
min = 1000010;//我们定义一个min,但要复制一个较大数,这样比较的时候比它小的再赋值给min
for (int j=0; j<=2*k; j++)
{
if ((i-k+j)>n||(i-k+j)<1)//如题目要求,下表不在1-n之间的则直接跳过。
{
continue; //这里我们用continue意味这次循环不符合进行下一次。因为如果下表小于1,但后面的循环下标符合,所以不能用break。
}
min = min > arr[i - k + j] ? arr[i - k + j] : min;//这里我们用判断语句将每个序号所对应的数与min比较,比它小的我们则赋值给min,然后再打印出来。
}
printf("%lld ", min);//最后我们打印每次循环的最小值
}
return 0;
}
样例输入
5
5 2 7 4 3
1
样例输出
2 2 2 3 3
第三次模拟比赛讲解已经结束,博主也是参考了https://blog.csdn.net/qq_44932745/article/details/129327344 和https://blog.csdn.net/m0_74183164/article/details/129453651
两篇博客加上自己的总结写出来的,如果有说明疑惑或者更优的方法可以评论或者私信。