习题2-1 位数(digit)
输入一个不超过10^9的正整数,输出它的位数。例如12735的位数是5。请不要使用任何数学函数,只用四则运算和循环语句实现。
#include <stdio.h>
int main()
{
int x,num=0;
scanf("%d",&x);
while(x)
{
x/=10;
num++;
}
printf("%d\n",num);
return 0;
}
习题2-2 水仙花数(daffodil)
输出100~999中的所有水仙花数。若3位数ABC满足ABC=A^3+B^3+C^3,则称其为水仙花数。例如153=1^3+5^3+3^3,所以153是水仙花数。
#include <stdio.h>
int main()
{
int i,a,b,c;
for(i=100; i<=999; i++)
{
a = i%10; /*个位*/
b = i/10%10; /*十位*/
c = i/100; /*百位*/
if(i == a*a*a + b*b*b + c*c*c)
printf("%d\n",i);
}
return 0;
}
结果:三位水仙花数有:153,370,371,407
习题2-3 韩信点兵(hanxin)
相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入3个非负整数a,b,c,表示每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100。
样例输入:2 1 6
样例输出:41
样例输入:2 1 3
样例输出:No answer
#include <stdio.h>
int main()
{
int i,a,b,c;
scanf("%d%d%d",&a,&b,&c);
for(i=10; i<=100; i++)
{
if(i%3==a && i%5==b && i%7==c)
{
printf("%d\n",i);
break;
}
}
if(i == 101)
printf("No answer\n");
return 0;
}
习题2-4 倒三角形(triangle)
输入正整数n<=20,输出一个n层的倒三角形。例如n=5时输出如下:
#########
#######
#####
###
#
#include <stdio.h>
int main()
{
int n,i,j;
scanf("%d",&n);
for(i=n;i>=1;i--)
{
for(j=1;j<=n-i;j++)
printf(" ");
for(j=1;j<=2*i-1;j++)
printf("#");
printf("\n");
}
return 0;
}
习题2-5 统计(stat)
输入一个正整数n,然后读取n个正整数a1,a2,...,an,最后再读一个正整数m。统计a1,a2,...,an中有多少个数小于m。提示:如果重定向和fopen都可以使用,哪个比较方便?
这道不会。。。欢迎指教!
习题2-6 调和级数(harmony)
输入正整数 n,输出 H(n) = 1 + 1/2 + 1/3 +...+ 1/n 的值,保留3位小数。例如n=3时答案为1.833。
#include <stdio.h>
int main()
{
int n,i;
double H = 0;
scanf("%d",&n);
for(i=1; i<=n; i++)
H += 1.0/i;
printf("%.3lf\n",H);
return 0;
}
习题2-7 近似计算(approximation)
计算pi/4 = 1 - 1/3 + 1/5 - 1/7 + ...,直到最后一项小于10^(-6)。
#include <stdio.h>
int main()
{
int i=1,flag=1;
double sum=0,item=1.0;
while(item>=1.0/1000000)
{
sum += flag*item;
flag *= -1;
i += 2;
item = 1.0/i;
}
printf("pi = %lf\n",sum*4);
return 0;
}
习题2-8 子序列的和(subsequence)
输入两个正整数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,。注意:本题有陷阱。
#include <stdio.h>
int main()
{
int i,n,m;
double sum=0;
scanf("%d%d",&n,&m);
for(i=n;i<=m;i++)
sum += 1.0/i/i;
printf("%.5lf\n",sum);
return 0;
}
本题陷阱:当n或m比较大时,i * i 会溢出,不能用 1.0 / ( i * i ) ,应该用 1.0 / i / i 。 或者改用long long数据类型。
习题2-9 分数化小数(decimal)
输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b<=10^6,c<=100。例如 a=1,b=6,c=4 时应输出 0.1667。
#include <stdio.h>
int main()
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
printf("%.*lf\n",c,1.0*a/b); /*新知识:格式控制符中,* 可由后边的变量替代!*/
return 0;
}
此种方法的问题是,当c较大时,超过十几位小数后边的小数部分都只显示零,不知道为什么。
以下是逐位计算小数的方法,就完全没问题了。(此段代码非我所写,注释是我加的,代码出处见博客尾。)
#include <stdio.h>
int main(void)
{
int a,b,c,mod,re,i,m,x,y;
while(scanf("%d%d%d",&a,&b,&c)==3)
{
printf("%d",a/b); /*输出整数部分*/
mod=a%b;
if(c>0)
{
printf(".");
for(i=1;i<c;i++) /*逐位计算输出c-1位小数*/
{
m=mod*10;
re=m/b;
printf("%d",re);
mod=m%b;
}
m=mod*10;
x=m/b;
mod=m%b; /*往后多算一位,四舍五入到我们所需的最后一位*/
m=mod*10;
y=m/b;
if(y>=5)
x++;
printf("%d\n",x); /*输出最后一位小数*/
}
}
return 0;
}
习题2-10 排列(permutation)
用 1,2,3,...,9 组成 3 个三位数 abc,def 和 ghi,每个数字恰好使用一次,要求 abc : def : ghi = 1 : 2 : 3。输出所有解。提示:不必太动脑筋。
#include<stdio.h>
int arr[10] = {0};/*数组arr用来记录1~9每个数字是否出现,与下标一一对应,出现为1,否则为0*/
int main()
{
int a,b,c,d,e,f,g,h,i,abc,def,ghi,t,sum;
for(a=1;a<=3;a++) /*a最大为3*/
for(b=1;b<=9;b++)
for(c=1;c<=9;c++)
for(d=2;d<=6;d++) /*d最小为2,最大为6*/
for(e=1;e<=9;e++)
for(f=1;f<=9;f++)
for(g=3;g<=9;g++) /*g最小为3*/
for(h=1;h<=9;h++)
for(i=1;i<=9;i++)
{
for(t=1;t<=9;t++)
arr[t] = 0;
arr[a] = 1;arr[b] = 1;arr[c] = 1;
arr[d] = 1;arr[e] = 1;arr[f] = 1;
arr[g] = 1;arr[h] = 1;arr[i] = 1;
sum = 0;
for(t=1;t<=9;t++) /*若数组累加和为9,表示1~9的数字全部出现*/
sum+=arr[t];
if(sum==9)
{
abc = a*100+b*10+c;
def = d*100+e*10+f;
ghi = g*100+h*10+i;
if(abc*2==def && abc*3==ghi)
printf("%d:%d:%d = 1:2:3\n",abc,def,ghi);
}
}
return 0;
}
结果:
192:384:576 = 1:2:3
219:438:657 = 1:2:3
273:546:819 = 1:2:3
327:654:981 = 1:2:3
还有网上的另一种方法,一定程度的逆向思维,精妙,运行速度比我的多层for循环嵌套快多了,我的程序循环次数有3*9*9*5*9*9*7*9*9 = 55801305次,而以下程序只有333-100 = 233次。
#include <stdio.h>
int main(void)
{
int x, y, z, a[10] = {0};
for(x = 100; x < 333; x++)
{
y = 2*x;
z = 3*x;
//令a[出现的数字] = 1
a[x/100] = a[x/10%10] = a[x%10] = 1;
a[y/100] = a[y/10%10] = a[y%10] = 1;
a[z/100] = a[z/10%10] = a[z%10] = 1;
int i, s = 0;
for(i = 1; i < 10; i++)
s += a[i];
if(s == 9)
printf("%d\t%d\t%d\n", x, y, z);
for(i = 1; i < 10; i++) //重新赋值为0
a[i] = 0;
}
return 0;
}
若有错误遗漏欢迎指出,欢迎交流讨论。
注:本文部分参考此篇博客:http://blog.csdn.net/litiouslove/article/details/7891700