您的位置:首页 > 其它

『算法学习笔记』13-15th day. 10道习题

2014-03-10 10:45 441 查看
2-1 位数 digit

输入一个不超过10^9的正整数输出它的位数。例如12735位数是5。不要使用任何数学函数,只用四则运算和循环语句实现。

1 #include <stdio.h>
2 int main()
3 {
4         int num,count;
5         scanf("%d",&num);
6         if(num>10)
7         {
8                 count=1;
9                 while(num>10)
10                 {
11                         num=num/10;
12                         count=count++;
13                 }
14                 printf("%d\n",count);
15         }
16         else printf("1\n");
17 }


注意:计数值要初始化! 同时注意位数的处理。

2-2 水仙花数 daffodil

输出100-999中所有的水仙花数。若三位数满足 ABC=A^3+B^3+C^3, 则ABC为水仙花数。

1 #include<stdio.h>
2 #include<math.h>
3 int main()
4 {
5         int i,j,k,num;
6         for(num=100;num<1000;num++)
7         {
8                 i=num/100;
9                 j=(num-i*100)/10;
10 //              j=num/10%10;
11                 k=num%10;
12 //              printf("%d ",num);
13                 if(num==(pow(i,3)+pow(j,3)+pow(k,3)))printf("%d\n",num);
14 //              if(num==(i*i*i+j*j*j+k*k*k))printf("%d\n",num);
15         }
16         return 0;
17 }


注意:个位的值时%10, 不是%100.

2-3 韩信点兵

韩信才智国人,从不清点自己军队的人数。只要让士兵先后以3人一排,五人一排,七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。

输入3个非负整数a,b,c 表示每种队形排尾的人数(a<3,b<5,c<7)输出总人数的最小值(或报告无解)。已知总人数小于10,不超过100。

样例输入:2 1 6

样例输出:41

样例输入:2 1 3 

样例输出:no answer

注意:题目要求用文件输入输出!

1 #include<stdio.h>
2 int main()
3 {
4         int num,a,b,c;
5 #ifdef LOCAL
6         freopen("exe2-3.in", "r", stdin);
7         freopen("exe2-3.out","w",stdout);
8 #endif
9         scanf("%d%d%d",&a,&b,&c);
10 #if 1
11         if((a>=3)||(b>=5)||(c>=7)||(a<0)||(b<0)||(c<0))
12         {
13                 printf("illegal input.\n");
14                 return 0;
15         }
16 #endif
17         for(num=10;num<=100;num++)
18         {
19                 if((num%3==a)&&(num%5==b)&&(num%7==c))
20                 {
21                         printf("%d\n",num);
22                         return 0;
23                 }
24         }
25         printf("no answer\n");
26         return 0;
27 }


采用了条件编译哟! 就是如果编译的时候加上 -DLOCAL 就用文件输出 否则就用标准输入输出哦!

下面是fopen版----用文件输入输出,但是不允许用重定向的情况下使用

1 #include<stdio.h>
2 int main()
3 {
4         FILE *fin, *fout;
5         int num,a,b,c;
6         printf("defined");
7         fin=fopen("exe2-3.in", "rb");
8         fout=fopen("exe2-3.out","wb");
9         fscanf(fin,"%d%d%d",&a,&b,&c);
10 #if 1
11         if((a>=3)||(b>=5)||(c>=7)||(a<0)||(b<0)||(c<0))
12         {
13                 printf("illegal input.\n");
14                 return 0;
15         }
16 #endif
17         for(num=10;num<=100;num++)
18         {
19                 if((num%3==a)&&(num%5==b)&&(num%7==c))
20                 {
21                         fprintf(fout,"%d\n",num);
22                         fclose(fin);
23                         fclose(fout);
24                         return 0;
25                 }
26         }
27         fprintf(fout, "no answer\n");
28         fclose(fin);
29         fclose(fout);
30         return 0;
31 }


fopen的好处是 在使用文件输入输出的时候你依然可以使用标准输入输出,非常的方便!太好用了!

备注:输入文件使用的是 exe2-3.in 输出文件使用的是exe2-3.in 后面的题目就省略不贴了。

edward@edward:~/Desktop/Algorithm$ cat exe2-3.in

2 1 3

edward@edward:~/Desktop/Algorithm$ cat exe2-3.out

no answer

2-4倒三角形 triangle

输入正整数n<=20,输出一个n层的倒三角形。例如n=5时输出如下:

#########

 #######

  #####

   ###

    #

1 #include<stdio.h>
2 int main()
3 {
4 #ifdef LOCAL
5         freopen("exe2-4.in","r",stdin);
6         freopen("exe2-4.out","w",stdout);
7 #endif
8         int i,j,k,n;
9         scanf("%d",&n);
10         for(i=1;i<=n;i++)
11         {
12                 for(j=1;j<i;j++) printf(" ");
13                 for(k=1;k<=2*(n-i)+1;k++) printf("#");
14                 printf("\n");
15         }
16         return 0;
17 }


下面是fopen版

1 #include<stdio.h>
2 int main()
3 {
4         FILE *fin, *fout;
5         fin=fopen("exe2-4.in","rb");
6         fout=fopen("exe2-4.out","wb");
7         int i,j,k,n;
8         fscanf(fin,"%d",&n);
9         for(i=1;i<=n;i++)
10         {
11                 for(j=1;j<i;j++) fprintf(fout," ");
12                 for(k=1;k<=2*(n-i)+1;k++) fprintf(fout,"#");
13                 fprintf(fout,"\n");
14         }
15         fclose(fin);
16         fclose(fout);
17         return 0;
18 }

2-5 统计

输入一个正整数n 然后读取n个正整数a1 ...an ,最后再读一个正整数m。 统计a1... an中有多少个整数的值小于m。

1 #include<stdio.h>
2 int main()
3 {
4 FILE *fin, *fout;
5 fin=fopen("exe2-5.in","wb");
6 fout=fopen("exe2-5.out","wb");
7 fprintf(fin, ""); //每次写入前清空上次的记录
8 fclose(fin);
9 fin=fopen("exe2-5.in","ab");//追加写
10 int m,i,j,k,n=0;
11 scanf("%d", &m);
12 for(i=0;i<m;i++)
13 {
14 scanf("%d", &j);
15 fprintf(fin,"%d ",j);
16 }
17 scanf("%d", &k);
18 fclose(fin);
19 fin=fopen("exe2-5.in","rb");
20 for(i=0;i<m;i++)
21 {
22 fscanf(fin, "%d",&j); //在没有重新打开和调整指针的情况下每次会默认直接读取下一个位置
23 printf("j=%d",j);
24 if(j>k)n++;
25 }
26 fclose(fin);
27 fclose(fout);
28 printf("%d\n", n);
29 return 0;
30 }


这道题其实很有意思,因为需要比较的数量是不确定的,而比较的数又是最后输入。
以前可能会想到使用数组动态分配一块内存,但这不是最佳的。现在从文件角度来看,这个问题极大的简化了!

只需要把要比较的值依次记录到文件,再依次读取就可以了,效率上佳。

2-6 调和级数

输入正整数n, 输出H(n) =1+1/2+1/3+....+1/n的值,保留3位小数。例如n=3时答案为 1.833

1 #include<stdio.h>
2 int main()
3 {
4         int i,n;
5         float sum=0;
6         scanf("%d",&n);
7         for(i=1;i<=n;i++)
8         {
9                 sum+=(float)1/i;
10         }
11         printf("%.3f\n",sum);
12         return 0;
13 }


这个题非常简单。下面时文件重定向版

1 #include<stdio.h>
2 int main()
3 {
4 #ifdef LOCAL
5         freopen("exe2-6.in","r",stdin);
6         freopen("exe2-6.out","w",stdout);
7 #endif
8         int i,n;
9         float sum=0;
10         scanf("%d",&n);
11         for(i=1;i<=n;i++)
12         {
13                 sum+=(float)1/i;
14         }
15         printf("%.3f\n",sum);
16         return 0;
17 }


下面是fopen版

1 #include<stdio.h>
2 int main()
3 {
4         FILE *fin,*fout;
5         fin=fopen("exe2-6.in","rb");
6         fout=fopen("exe2-6.out","wb");
7         int i,n;
8         float sum=0;
9         fscanf(fin,"%d",&n);
10         for(i=1;i<=n;i++)
11         {
12                 sum+=(float)1/i;
13         }
14         fprintf(fout,"%.3f\n",sum);
15         fclose(fin);
16         fclose(fout);
17         return 0;
18 }


2-7 近似计算

计算pi/4=1-1/3+1/5-1/7+.... 直到最后一项小于10^(-6)

1 #include<stdio.h>
2 #include<math.h>
3 int main()
4 {
5         float sum=1,factor=pow(10,-6),temp;
6         int i=3;
7         temp=(float)1/3;
8         while(temp>=factor)
9         {
10                 if(i%4==1) sum+=temp;
11                 else sum-=temp;
12                 i+=2;
13                 temp=(float)1/i;
14         }
15         printf("%f\n",sum);
16         printf("pi/4=%f",atan(1.0));
17         return 0;
18 }


注:第二个输出是为了对比结果用方便加的。

浮点数比较的地方好像有问题。

2-8 子序列之和

输入两个正整数 n<m<10^6 输出1/n^2+1/(n+1)^2 +...+ 1/m^2, 保留5位小数。例如n=2,m=4时的答案时0.42361,n=65536,m=655360时答案是0.00001.

注意:本题有缺陷。

1 #include<stdio.h>
2 #include<math.h>
3 int main()
4 {
5 int n,m,i;
6 scanf("%d %d", &n, &m);
7 float sum=0;
8 for(i=n;i<=m;i++)
9 {
10 sum+=pow((float)1/i,2);
11 }
12 printf("%.5f\n",sum);
13 return 0;
14 }


备注:没有发现缺陷是什么。

2-9 分数化小数

输入整数a,b,c, 输出a/b的小数形式,精确到小数点后c位。a,b<=10^6, c<=100

例如a=1,b=6,c=4时应该输出0.1667.

1 #include<stdio.h>
2 int main()
3 {
4 int a,b,c;
5 scanf("%d%d%d",&a,&b,&c);
6 printf("%.*lf\n",c,(double)a/b);
7 return 0;
8 }

printf的特殊用法,对于m.n的格式可以用如下方法表示 

    int a,b,m,n;   

    printf("%*.*lf\n",m,n,(double)a/b);

    前边的*定义的是总的宽度,后边的定义的是输出的个数。分别对应外面的参数m和n 。 这种方法的好处是可以在语句之外对参数m和n赋值,从而控制输出格式。

2-10 排列

用1,2,3...9组成三个三位数,abc, def,ghi,每个数字恰好使用一次,要求:

abc:def:ghi=1:2:3.输出所有解。提示:不用太动脑筋。

1 #include<stdio.h>
2 int main()
3 {
4 int a ,b,c,d,e,f,g,h,i, m,n,o;
5 for(a=1;a<10;a++)
6 {
7 for(b=1;b<10;b++)
8 {
9 for(c=1;c<10;c++)
10 {
11 for(d=1;d<10;d++)
12 {
13 for(e=1;e<10;e++)
14 {
15 for(f=1;f<=10;f++)
16 {
17 for(g=1;g<10;g++)
18 {
19 for(h=1;h<10;h++)
20 {
21 for(i=1;i<10;i++)
22 {
23
24 if(a!=b&&a!=c&&a!=d&&a!=e&&a!=f&&a!=g&&a!=h&&a!=i
25 &&b!=c&&b!=d&&b!=e&&b!=f&&b!=g&&b!=h&&b!=i
26 &&c!=d&&c!=e&&c!=f&&c!=g&&c!=h&&c!=i
27 &&d!=e&&d!=f&&d!=g&&d!=h&&d!=i
28 &&e!=f&&e!=g&&e!=h&&e!=i
29 &&f!=g&&f!=h&&f!=i
30 &&g!=h&&g!=i
31 &&h!=i)
32 {
33
34 m=a*100+b*10+c;
35 n=d*100+e*10+f;
36 o=g*100+h*10+i;
37 if(n==2*m&&o==3*m)
38 printf("%d %d %d\n", m,n,o);
39 }
40 }
41 }
42 }
43 }
44 }
45 }
46 }
47 }
48 }
49 return 0;
50 }
~
这道题貌似解法很多,不过我没有用数组和其他复杂的方法解。

这个应该是最暴力的方法了吧。哈哈!

解答

192 384 576

219 438 657

273 546 819

327 654 981
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: