算法入门经典——第2章例题(汇总+心得)

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版,效果等同于紫书版。只是实现方式有点不同。


 

 未完待续........

posted @ 2019-07-01 18:20 逸非安逸 阅读(...) 评论(...) 编辑 收藏