《算法竞赛入门经典-第二版》课后习题答案
第二章
习题2-1 水仙花数(daffodil)
输出100~999中的所有水仙花数。若3位数ABC满足ABC=A3+B3+C3,则称其为水仙花数。例如153=13+53+33,所以153是水仙花数。
#include <stdio.h>
int main(){
int a,b,c,i;
for(i =100;i<1000;i++){
a=i/100;
b=(i%100)/10;
c=i%10;
if(i==a*a*a+b*b*b+c*c*c){
printf("%d ",i);
}
}
return 0;
}
习题2-2 韩信点兵(hanxin)
相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入包含多组数据,每组数据包含3个非负整数a,b,c,表示每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100。输入到文件结束为止。
样例输入:
2 1 6
2 1 3
样例输出:
Case 1: 41
Case 2: No answer
#include<stdio.h>
int main(){
int i=10;
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
while(i<100){
if((i%3==a)&&(i%5==b)&&(i%7==c))
{
printf("%d",i);
return 0;
}
i++;
}
printf("No answer");
}
习题2-3 倒三角形(triangle)
输入正整数n≤20,输出一个n层的倒三角形。例如,n=5时输出如下:
#########
#######
#####
###
#
#include<stdio.h>
int main(){
int n,i=0;
scanf("%d",&n);
while (n>0){
for(int j=0;j<i;j++){
printf(" ");
}
for(int j=0;j<2*n-1;j++){
printf("#");
}
for(int j=0;j<i;j++){
printf(" ");
}
printf("\n");
i++;
n--;
}
}
习题2-4 子序列的和(subsequence)
输入两个正整数n<m<106,输出,保留5位小数。输入包含多组数据,结束标记为n=m=0。提示:本题有陷阱。
样例输入:
2 4
65536 655360
0 0
样例输出:
Case 1: 0.42361
Case 2: 0.00001
陷阱:当m很大时,使用int存储m^2会溢出。
#include<stdio.h>
int main(){
int n,m,cnt=0;
while(1){
scanf("%d%d",&n,&m);
if(n==0&&m==0){
break;
}
double sum=0.0;
for(long long i=n;i<=m;i++){
sum+=1.0/(i*i);
}
// 或者
// for(int i=n;i<=m;i++){
// sum+=1.0/i/i;
// }
printf("Case %d: %.5lf\n",++cnt,sum);
}
return 0;
}
习题2-5 分数化小数(decimal)
输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b≤106,c≤100。输入包含多组数据,结束标记为a=b=c=0。
样例输入:
1 6 4
0 0 0
样例输出:
Case 1: 0.1667
#include <stdio.h>
int main(){
int a,b,c,count=0;
while(1){
scanf("%d%d%d",&a,&b,&c);
if(a==0&&b==0&&c==0){
break;
}
int num[110]={0};
//整数结果部分
int integer=a/b;
a=a%b;
int size = 0;
//求出小数点后c+1位小数
while (c+1>size){
num[size]=(a*10)/b;
a=(a*10)%b;
size++;
}
//对小数点后1-c位进位判断
if(num[size]>=5){
num[size-1]++;
for(int i=size-1;i>0;i--){
if(num[i]=10){
num[i]=0;
num[i-1]++;
}
}
}
//判断小数点后一位需不需要进行对整数部分进行进位判断
if(num[0]==10){
num[0]=0;
integer++;
}
//结果输出
printf("Case %d: ",++count);
printf("%d.", integer);
for(int i=0;i<size-1;i++){
printf("%d",num[i]);
}
}
}
习题2-6 排列(permutation)
用1,2,3,…,9组成3个三位数abc,def和ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3。按照“abc def ghi”的格式输出所有解,每行一个解。提示:不必太动脑筋。
#include <stdio.h>
#include <cstring>
void numCount(int number,int *num){
++num[number/100];
++num[number%100/10];
++num[number%10];
}
int main(){
int num[10];
bool flag=true;
for(int i=123;i<=987/3;i++){
flag= true;
//数组重新赋0
memset(num,0, sizeof(num));
//记录每个数字出现次数
numCount(i,num);
numCount(2*i,num);
numCount(3*i,num);
//判断是否每个数字出现一次
for(int j=1;j<10;j++)
{
if(num[j]!=1){
flag= false;
break;
}
}
//结果输出
if(flag){
printf("%d %d %d \n",i,2*i,3*i);
}
}
}