Loading... 最后因为时间原因只做了三道题,决赛也懒得去了,就小小回顾一下吧 ### 题目A  <img src="https://img.yan-lin.cn/i/2024/12/30/67725892ab1b8.png" alt="屏幕截图 2024-12-15 171222.png" style="zoom:67%;" style="">  #### 思路 从一个点到下一个点有正着走和反着走两种方式,找出最短的路线并累加就可以找出最短距离了。 #### 注意点 要注意最后要回到第一个点,最后还有这一段要记得加上。 #### 示例代码 C语言: ```c #include<stdio.h> #include<math.h> #include<stdlib.h> int main(){ int n,m,a[200000]; scanf("%d%d",&n,&m); for (int i=0;i<m;i++) { scanf("%d",&a[i]); } int now=a[0]; int answer=0; for (int i=0;i<m; i++) { int next=a[(i+1)%m];//记录下一个点的位置 int distant1=abs(next-now);//正着走 int distant2=n-distant1;//反着走 answer+=(distant1<distant2?distant1:distant2);//累加答案 now=next;//更新当前位置 } printf("%d\n", answer); return 0; } ``` Python: ```python n,m=map(int, input().split()) a=list(map(int, input().split())) answer=0 for i in range(m): now=a[i] next=a[(i+1)%m] dis1=abs(now - next) dis2=n-dis1 answer+=min(dis1, dis2) print(answer) ``` 两种语言逻辑都是一样的,但是可以发现Python的代码简短很多,但是运行时间会长很多。 ### 题目B  <img src="https://img.yan-lin.cn/i/2024/12/30/67725b50567b0.png" alt="image-20241230163502146" style="zoom:67%;" style=""> #### 思路 使用枚举法,每过一天就检测一次是否为回文日。由于C语言的限制,不是特别方便,所以要使用`snprintf`函数来拼接字符串,并用字符串的形式判断是否为回文。 #### 注意点 输出时注意在必要的地方补零,输入的时候也要注意正确存取。 #### 示例代码 ```c #include<stdio.h> #include<string.h> typedef struct B { int y;//年 int m;//月 int d;//日 }DAY; int days(int month){//判断一个月有多少天 if(month==2) return 28; if(month<=7){ if(month%2==0) return 30; } else return 31; if(month%2==0) return 31; return 30; } int isHui(char *str){//判断是不是回文,使用字符串 for(int i=0;i<4;i++){ if(str[i]!=str[7-i]) return 0; } return 1; } int main(){ int t; DAY a[10]; scanf("%d",&t); for(int i=0;i<t;i++){ scanf("%4d%2d%2d",&a[i].y,&a[i].m,&a[i].d);//通过精准输入把年月日输入 } for(int i=0;i<t;i++){ int m=a[i].m,y=a[i].y,d=a[i].d; char date[10];//存储这一天的字符串 while (1) { snprintf(date,sizeof(date),"%04d%02d%02d",y,m,d);//将年月日补齐存入date字符串 if(isHui(date)){ printf("%04d%02d%02d\n",y,m,d); break; } d++;//天数加一 if(d>days(m)){//如果到下一个月 m++; if(m==13){//如果到下一年 m=1; y++; } d=1; } } } return 0; } ``` ### 题目C  <img src="https://img.yan-lin.cn/i/2024/12/30/67726957b23aa.png" alt="image-20241230173448149" style="zoom:67%;" style=""> #### 思路 通过枚举法,定一移一的方式寻找存在的数列 #### 注意点 并不需要全部枚举一遍,最大的数就是除以二的数左右的数字之和,所以可以控制边界减少枚举次数。同时在检测到和超过原数时也可以直接跳出,减少枚举次数。 同时可以使用求和公式来减少运行时间,否则貌似会超时。 #### 示例代码 ```c #include<stdio.h> typedef struct C { int i;//左边界 int j;//又边界 }C; int main(){ int n,num=0; C ans[100000]; scanf("%d",&n); for (int k=2;k*(k-1)/2<n;k++) {//边界是除以二的数字左右 if ((n-k*(k-1)/2)%k==0) {//运用求和公式 int a=(n-k*(k-1)/2)/k; ans[num].i=a;//存入左边界 ans[num].j=a+k-1;//存入右边界 num++;//记录有几个符合条件的 } } printf("%d\n",num); for(int i=0;i<num;i++){ for(int j=ans[i].i;j<=ans[i].j;j++) printf("%d ",j); printf("\n"); } return 0; } ``` 最后修改:2025 年 06 月 02 日 © 允许规范转载 赞 不用打赏哦!