本文结合PTA专项练习带领读者掌握循环结构,刷题为主注释为辅,在代码中理解思路,其它不做过多叙述。
7-1 循环-sum
统计给定的n(n<10000)个数中,所有正数的和与负数的和。
输入格式:
第一行是一个n,n的范围已在题意中给出。
接下来一行输入n个整数。
输出格式:
输出两个数字,第一个为正数和,第二个为负数和,以空格隔开
如果没有正数或者负数则输出“no positive number 负数和”或“正数和 no negative number”,
如果正数负数都没有,则输出"no positive number no negative number"。
输入样例:
在这里给出一组输入。例如:
3 1 2 -1
输出样例:
在这里给出相应的输出。例如:
3 -1
#include <stdio.h> int main() { int n; scanf("%d",&n); int a; int sum=0,count=0,all=0,geshu=0; for(int i=0;i<n;i++) { scanf("%d",&a); if(a>0) { sum+=a; count++; } else if(a<0) { all+=a; geshu++; } } if(count==0&&geshu==0) { printf("no positive number no negative number"); } else if(count==0&&geshu!=0) { printf("no positive number %d",all); } else if(count!=0&&geshu==0) { printf("%d no negative number",sum); } else { printf("%d %d",sum,all); } }
7-2 循环-奇怪的斐波那契数列
在繁荣山丘,有一种奇怪的斐波那契数列,人们不关心他第几项是多少,只关心它能否被3整除。在这里,,F(0) = 7, F(1) = 11, F(n) = F(n-1) + F(n-2) (n>=2)。
请你判断一下第n项是否能被3整除?
输入格式:
输入一行,包括1个正整数n。
输出格式:
若F(n)能被3整除,则输出"YES",否则输出"NO"。
输入样例:
在这里给出一组输入。例如:
5
输出样例:
在这里给出相应的输出。例如:
NO
思路:把原式 F(n) = F(n-1) + F(n-2) 等式左右两边都对3取模,
即 F(n) %3 = (F(n-1) + F(n-2) ) %3,
此式子由数论知识易知可以进一步等价于 F(n) %3 = (F(n-1) %3 + F(n-2) %3) %3
而F(0)%3=1,F(1)%3=2,F(2)%3=(F(1)%3+F(0)%3)%3=0,同理 F(3)%3=2,F(4)%3=2,F(5)%3=1,F(6)%3=0,F(7)%3=1,F(8)%3=1,F(9)%3=2
可以发现 F(0)%3=1,F(1)%3=2 ,又 F(8)%3=1,F(9)%3=2,表明此时已出现循环,即一个完整的循环为:{1,2,0,2,2,1,0,1}
#include <stdio.h> int main() { int a[8]={1,2,0,2,2,1,0,1}; int n; scanf("%d",&n); if (a[n%8]==0) { printf("YES"); } else { printf("NO"); } return 0; }
7-3 循环-字符统计
输入一行字符,请分别统计出其中英文字母、空格、数字和其他字符的个数。
输入格式:
输入仅包含一行字符串,包含空格。字符串长度小于100。
输出格式:
输出包括4个数字,分别表示英文字母、空格、数字和其他字符的个数,以空格隔开。
输入样例:
在这里给出一组输入。例如:
You have 7 new messages!
输出样例:
在这里给出相应的输出。例如:
18 4 1 1
#include <stdio.h> int main() { int letterCount=0,spaceCount=0,digitCount=0,otherCount=0; char c; while((c=getchar())!='\n'){ if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){ letterCount++; } else if(c==' '){ spaceCount++; } else if(c>='0'&&c<='9'){ digitCount++; } else{ otherCount++; } } printf("%d %d %d %d",letterCount,spaceCount,digitCount,otherCount); return 0; }
7-4 沙漏
给一个正整数 n,表示一个高度为 2 * n - 1 的沙漏,请打印出这个沙漏。
输入格式:
输入一个正整数 n (1 <= n <= 20)。
输出格式:
输出一个高度为 2 * n - 1 的沙漏(每行末尾换行无空格,不要输出多余空格)。
输入样例:
在这里给出一组输入。例如:
3
输出样例:
在这里给出相应的输出。例如:
##### ### # ### #####
#include <stdio.h> int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1;j<i;j++) { printf(" "); } for(int j=i;j<=n;j++) { printf("#"); } for(int j=n-1;j>=i;j--) { printf("#"); } printf("\n"); } for(int i=n-1;i>=1;i--) { for(int j=1;j<i;j++) { printf(" "); } for(int j=i;j<=n;j++) { printf("#"); } for(int j=n-1;j>=i;j--) { printf("#"); } printf("\n"); } }
7-1 求整数段和
给定两个整数A和B,输出从A到B的所有整数以及这些数的和。
输入格式:
输入在一行中给出2个整数A和B,其中−100≤A≤B≤100,其间以空格分隔。
输出格式:
首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中按Sum = X
的格式输出全部数字的和X
。
输入样例:
-3 8
输出样例:
-3 -2 -1 0 1 2 3 4 5 6 7 8 Sum = 30
#include <stdio.h> int main(){ int a,b,sum=0,count=0; scanf("%d %d",&a,&b); if(a>=-100&&a<=b&&b<= 100){ for(int i=a;i<=b;i++){ count++; printf("%5d",i); sum+=i; if(count%5==0||i==b){ printf("\n"); } } printf("Sum = %d",sum); } return 0; }
7-2 循环-aaaa
给一个数 a 和一个数 n,求 a + aa + aaa + aaaa + … + aaa…aaa (最后一项有 n 个 a)的和。
输入格式:
输入两个数 a 和 n(1 <= a <= 9 ,1 <= n <= 6) 。
输出格式:
输出a + aa + aaa + aaaa + … + aaa…aaa (最后一项有 n 个 a)的和。
输入样例:
在这里给出一组输入。例如:
4 6
输出样例:
在这里给出相应的输出。例如:
493824
错误示例:
int a,n; scanf("%d %d",&a,&n); int sum=a; for(int i=2;i<=n;i++) { a=a*10+a; //如果这样写,会导致a的值被覆盖。 //例如a为4时,该行使a变成40+4,但再循环时变为440+44,而不是444 sum+=a; } printf("%d",sum);
因此,可以用一个中间变量解决该问题:
#include <stdio.h> int main() { int a,n; scanf("%d %d",&a,&n); int t=a,sum=a;; for(int i=2;i<=n;i++) { t=t*10+a; sum+=t; } printf("%d",sum); }
7-3 循环-完数
一个数如果恰好等于它的因子(不包括它本身)之和,这个数就称为“完数”。例如:6的因子为1、2、3,而6=1+2+3,因此6是“完数”。给定一个数,判断它是否是“完数”。
输入格式:
输入一个正整数n(n<10000)。
输出格式:
如果n为“完数”,输出“YES”;否则输出“NO”。
输入样例:
在这里给出一组输入。例如:
6
输出样例:
在这里给出相应的输出。例如:
YES
//本题采用数组实现,具体思路为:先把数组中元素赋为0,遍历时若找到因子则存入数组中,最后遍历数组即可 #include <stdio.h> int main() { int n; scanf("%d",&n); int a[n]; for(int i=0;i<n;i++) { a[i]=0; } for(int i=1;i<n;i++) { if(n%i==0) a[i-1]=i; } int sum=0; for(int i=0;i<n;i++) { sum+=a[i]; } if(sum==n) printf("YES"); else printf("NO"); }
7-4 输出三角形字符阵列
本题要求编写程序,输出n行由大写字母A开始构成的三角形字符阵列。
输入格式:
输入在一行中给出一个正整数n(1≤n<7)。
输出格式:
输出n行由大写字母A开始构成的三角形字符阵列。格式见输出样例,其中每个字母后面都有一个空格。
输入样例:
4
输出样例:
A B C D E F G H I J
#include <stdio.h> int main() { int n; scanf("%d",&n); char c='A'; for(int i=1;i<=n;i++) { for(int j=n;j>=i;j--) { printf("%c ",c); c++; } printf("\n"); } }
7-5 打印九九口诀表
下面是一个完整的下三角九九口诀表:
1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
本题要求对任意给定的一位正整数N
,输出从1*1
到N*N
的部分口诀表。
输入格式:
输入在一行中给出一个正整数N
(1≤N
≤9)。
输出格式:
输出下三角N*N
部分口诀表,其中等号右边数字占4位、左对齐。
输入样例:
4
输出样例:
1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16
#include <stdio.h> int main() { int n,i,j; scanf("%d",&n); for(i=1;i<=n;i++) { for(j=1;j<=i;j++) { printf("%d*%d=%-4d",j,i,i*j); } printf("\n"); } }
7-6 换硬币
将一笔零钱换成5分、2分和1分的硬币,要求每种硬币至少有一枚,有几种不同的换法?
输入格式:
输入在一行中给出待换的零钱数额x∈(8,100)。
输出格式:
要求按5分、2分和1分硬币的数量依次从大到小的顺序,输出各种换法。每行输出一种换法,格式为:“fen5:5分硬币数量, fen2:2分硬币数量, fen1:1分硬币数量, total:硬币总数量”。最后一行输出“count = 换法个数”。
输入样例:
13
输出样例:
fen5:2, fen2:1, fen1:1, total:4 fen5:1, fen2:3, fen1:2, total:6 fen5:1, fen2:2, fen1:4, total:7 fen5:1, fen2:1, fen1:6, total:8 count = 4
//total=fen5*5+fen2*2+fen1*1,所以从每种币的最大值开始递减,比如5分的币,数量最大值就是总价值(n-2-1)/5 时间复杂度分析 #include <stdio.h> int main() { int n,fen5,fen2,fen1,count=0; scanf("%d", &n); for (fen5=(n-2-1)/5;fen5>0;fen5--) { for (fen2=(n-5-1)/2;fen2>0;fen2--) { fen1=n-(fen5*5+fen2*2); if(fen5*5+fen2*2+fen1==n&&fen1>=1) { count++; printf("fen5:%d, fen2:%d, fen1:%d, total:%d\n",fen5,fen2,fen1,fen5+fen2+fen1); } } } printf("count = %d", count); return 0; }
7-7 猜数字游戏
猜数字游戏是令游戏机随机产生一个100以内的正整数,用户输入一个数对其进行猜测,需要你编写程序自动对其与随机产生的被猜数进行比较,并提示大了(“Too big”),还是小了(“Too small”),相等表示猜到了。如果猜到,则结束程序。程序还要求统计猜的次数,如果1次猜出该数,提示“Bingo!”;如果3次以内猜到该数,则提示“Lucky You!”;如果超过3次但是在N(>3)次以内(包括第N次)猜到该数,则提示“Good Guess!”;如果超过N次都没有猜到,则提示“Game Over”,并结束程序。如果在到达N次之前,用户输入了一个负数,也输出“Game Over”,并结束程序。
输入格式:
输入第一行中给出两个不超过100的正整数,分别是游戏机产生的随机数、以及猜测的最大次数N。最后每行给出一个用户的输入,直到出现负数为止。
输出格式:
在一行中输出每次猜测相应的结果,直到输出猜对的结果或“Game Over”则结束。
输入样例:
58 4 70 50 56 58 60 -2
输出样例:
Too big Too small Too small Good Guess!
#include <stdio.h> int main() { int number,n,i,m,flag=0; scanf("%d %d",&number,&n); for(i=1;i<=n;i++) { scanf("%d",&m); if(m<0) break; if(m>number) printf("Too big\n"); if(m<number) printf("Too small\n"); if(m==number) { if(i==1) { flag=1; printf("Bingo!\n"); break; } if(i== 2||i==3) { flag=1; printf("Lucky You!\n"); break; } if(i>3) { flag=1; printf("Good Guess!\n"); break; } } } if (flag==0) printf("Game Over\n"); return 0; }