2.1 for循环
例2-1:断形如aabb式的四位数是否为完全平方数
思路一:直接暴力模拟
1 #include<stdio.h> 2 #include<math.h> 3 int main(){ 4 int n,m; 5 for(int a=1;a<=9;a++) 6 for(int b=0;b<=9;b++){ 7 n=a*1100+b*11; 8 m=floor(sqrt(n)+0.5);//注解详见下方(1) 9 if(m*m==n)printf("%d\n",n); 10 } 11 return 0; 12 } 13 /* 14 (1)防止计算机经过大量计算后,由于误差产生的影响 15 如:整数1编程了0.999999999,所以为了减少误差一般四舍五入 16 */
思路二:枚举平方根x,避开开方操作
1 #include<stdio.h> 2 int main(){ 3 int n; 4 for(int x=1;;x++){ 5 n=x*n; 6 if(n<1000)continue; 7 if(n>9999)break; 8 int a=n/100;//取前面两位数 9 int b=n%100;//取后面两位数 10 if(a/10==a%10&&b/10==b%10)printf("%d\n",n); 11 //再比较所取数前后时候一样 12 } 13 return 0; 14 }
从算法复杂度看,思路二明显优于思路一,但思路一更容易想到
2.2 while循环和do-while循环
例题2-2 3n+1问题:
猜想:对于任意大于1的自然数n,若n为奇数,则将n变成3n+1,否则变为n的一半。经过若干次这样的变换,一定会使n变为1.例如3->10->5->16->8->4->2->1.
输入n,输出变换的次数,n≤10的9次方
1 //输入范围 n<=10 9次方 2 #include<stdio.h> 3 void MyFuntion(){ 4 int n; 5 scanf("%d",&n); 6 int i=0; 7 while(n!=1){ 8 if(n%2)n=3*n+1; 9 else n/=2; 10 i++; 11 } 12 printf("%d\n",i); 13 } 14 //紫书版1.0 15 void standard1(){ 16 int n,count=0; 17 scanf("%d",&n); 18 while(n>1){ 19 if(n%2==1)n=n*3+1; 20 else n/=2; 21 count++; 22 // printf("n=%d\n%d\n",n,count); 23 } 24 printf("%d\n",count); 25 } 26 //紫书版1.1 27 void standard2(){ 28 int n2,count=0; 29 scanf("%d",&n2); 30 long long n=n2; 31 while(n>1){ 32 if(n%2==1)n=n*3+1; 33 else n/=2; 34 count++; 35 } 36 printf("%d\n",count); 37 } 38 //for循环版 39 void normal(){ 40 int n,i; 41 scanf("%d",&n); 42 for(i=0;n!=1;i++){ 43 if(n%2==1)n=n*3+1; 44 else n/=2; 45 } 46 printf("%d\n",i); 47 } 48 int main(){ 49 return 0; 50 }
紫书1.1版与1.0的区别在于,1.1版考虑到了int数据类型的数据范围(第一章中有认真做实验的话,会很自然的发现这个问题),防止了数据溢出造成问题
例题2-3 近似计算
计算pi/4=1-1/3+1/5-1/7+.........,直到最后一项小于1e-6。
1 #include<stdio.h> 2 //紫书代码 3 void sample(){ 4 double sum=0; 5 for(int i=0;;i++){ 6 double term=1.0/(i*2+1); 7 if(i%2==0)sum+=term; 8 else sum-=term; 9 if(sum<1e-6)break; 10 } 11 printf("%.6f\n",sum); 12 } 13 14 //do-while版 15 void MyFuntion(){ 16 double sum=0; 17 int i=0; 18 do{ 19 double term=1.0/(i*2+1); 20 if(i%2)sum-=term; 21 else sum+=term; 22 }while(sum<1e-6); 23 } 24 int main(){ 25 26 return 0; 27 }
因为标题说do-while循环,所以在紫书版的基础上,我自己写了个do-while版,效果等同于紫书版。只是实现方式有点不同。
未完待续........