《算法竞赛入门经典-第二版》第二章习题答案(UVA OJ已pass)

                    《算法竞赛入门经典-第二版》课后习题答案

                                           第二章

习题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);
       }
   }
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值