问题分析:每次循环表示报一次数,在一次循环内判断当前数i是否为7的倍数或含有数字7。若满足条件则跳过,判断跳过的是谁,计数;不满足则继续循环。
我们用total_count表示当前报的总数(除去跳过的数),i表示报数到了哪个数,count[4]存储甲乙丙丁的跳过数。
以下是我的用时0ms,内存占用404.0KB,满分100的代码:
1 #include <stdio.h> 2 3 int test_seven(int num); 4 5 int main(){ 6 int total_count = 0; 7 int i = 1; 8 int n = 0; 9 int count[4] = {0,0,0,0}; 10 scanf("%d",&n); 11 for(;total_count < n;i ++){ 12 int num = 0; 13 if(test_seven(i) || i % 7 == 0){ 14 num = i % 4; 15 switch(num){ 16 case 1: 17 count[0]++;break; 18 case 2: 19 count[1]++;break; 20 case 3: 21 count[2]++;break; 22 case 0: 23 count[3]++;break; 24 } 25 } 26 else total_count ++; 27 } 28 //输出 29 int j = 0; 30 for(;j < 4;j ++) 31 printf("%d ",count[j]); 32 return 0; 33 } 34 35 //判断是否带有7 36 int test_seven(int num){ 37 while(num){ 38 if(num % 10 == 7)return 1; 39 else num /= 10; 40 } 41 return 0; 42 }
注意数字中是否带有7的方法:
循环中判断除10是否余7(个位是否为7),若满足则返回true;若不满足,整除10并赋值自己(减一位,即若为878,则整除后结果为87,继续判断个位),直到为0跳出循环。
另外,CSDN博主 海岛Blog https://tigerisland.blog.csdn.net/article/details/104206619 思路相同,但代码更为简洁,粘贴至此学习:
1 /* CCF201912-1 报数 */ 2 3 #include <stdio.h> 4 5 #define N 4 6 7 int have7(int n) 8 { 9 while(n) 10 if(n % 10 == 7) return 1; 11 else n /= 10; 12 return 0; 13 } 14 15 int main(void) 16 { 17 int n, num = 1, count = 1, cnt[N] = {0, 0, 0, 0}; 18 19 scanf("%d", &n); 20 while(count <= n) { 21 if(num % 7 == 0 || have7(num)) 22 cnt[(num - 1) % N]++; 23 else 24 count++; 25 num++; 26 } 27 28 int i; 29 for(i = 0; i < N; i++) 30 printf("%d ", cnt[i]); 31 32 return 0; 33 } 34 ———————————————— 35 版权声明:本文为CSDN博主「海岛Blog」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 36 原文链接:https://tigerisland.blog.csdn.net/article/details/104206619
给我自己的总结:
1、多个同类型的变量声明可放一行解决。
2、for循环内用不到变量i,为何不用while解决?
3、观察可发现num和count[j]的j有关联,不需要再用switch,只需一行代码即可解决。
4、将题中的人数4宏定义成N,使程序更加具有一般性。