STD高级语言程序设计第三天(满分答案,附赠本人程序的解析)

7-1 打印沙漏 (20 分)

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

*****
 ***
  *
 ***
*****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入格式:

输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

输出格式:

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

输入样例:

19 *

结尾无空行

输出样例:

*****
 ***
  *
 ***
*****
2

结尾无空行

#include<stdio.h>
int main()
{
    //接收整数和符号
    int a;
    char b;
    scanf("%d %c",&a,&b);
    
    //a==1是其中的一个测试点,如果不写的话,小编在else中写的代码在a==1时会出错
    if(a==1)
    {
        printf("%c\n",b);
        printf("0");
    }
    
    else
    {
        //利用sum计算第一行到中间行只打印一个符号的总符号个数
        //i最后会为第一行符号的个数
        int sum=0,i=1;
        
        //沙漏可近似的看成对称,但也不对称,因为一个符号的行数只有一行
        //所以用我们输入的整数a加1除以2,就是我们上半部分符号总数的最大值
        while(sum<=(a+1)/2)
        {
            sum+=i;
            i+=2;
        }
        
        //因为sum大于(a+1)/2之后循环才会终止,所以我们要减去一次i
        //又因为上个循环中 i+=2在sum+=i之后进行
        //所以我们的i先减去2,再将sum减去i
        //为什么又减了一次2,还是因为i+=2在循环体后面
        //在sum刚到临界值我们加了一次i,但是在后面i又进行了i+=2
        //所以i减去一次2,才是sum在临界值加的那个i
        i-=2;
        sum-=i;
        i-=2;
        
        //上面说i是第一行符号个数,此时赋值给j
        int j=i;
        //循环体我们将沙漏的上半部分打印完毕
        while(j>=1)
        {
            //利用循环打印空格,其实自己第一次做可以先不打印空格
            //只打印符号和换行,然后输出,看看输出效果,符合预期,添加空格,不符合预期,修改代码
            //第一行没有空格,每多输出一行空格+1,j每次增加2,i不变
            //所以(i-j)/2,读者可以自己代入例子试一下
            for(int x=(i-j)/2;x>0;x--)
                printf(" ");
            
            //利用循环打印符号
            for(int k=j;k>0;k--)
                printf("%c",b);
            
            //符号每多一行就少两个,所以j要减去2
            j-=2;
            
            //每行的符号打印完毕后换行
            printf("\n");
        }
/*
以用例,循环体执行完毕后的结果应该是:

*****
 ***
  *

*/
        
        //上面循环体执行完毕后j的值为-1
        //而下半部分的第一行是三个符号,所以我们将j加4
        //有兴趣的读者可以自己试一试j+=2,下半部分打印出来的第一行应该是一个符号
        j+=4;
        
        //i是第一行符号个数,j是每一行符号的个数,j的最大值是i
        //即在最后一行j的值是i
        while(j<=i)
        {
            //还是先打印空格
            for(int x=(i-j)/2;x>0;x--)
                printf(" ");
            
            //打印符号
            for(int k=0;k<j;k++)
                printf("%c",b);
            
            //每行打印完换行
            printf("\n");
            
            //每多打印一行,每行符号+2
            j+=2;
        }
        
        //打印剩下符号的个数
        //sum是上半部分的符号总个数,所以下半部分的符号个数是sum-1
        //最后a-sum-(sum-1)
        printf("%d",a-2*sum+1);
    }
    
    return 0;
}

 7-2 求整数段和 (10 分)

 给定两个整数A和B,输出从A到B的所有整数以及这些数的和。

输入格式:

输入在一行中给出2个整数A和B,其中−100≤A≤B≤100,其间以空格分隔。

输出格式:

首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中按Sum = X的格式输出全部数字的和X

输入样例:

-3 8

结尾无空行

输出样例:

   -3   -2   -1    0    1
    2    3    4    5    6
    7    8
Sum = 30

结尾无空行

#include<stdio.h>
int main()
{
    //接收两个整数
    int a,b;
    scanf("%d%d",&a,&b);
    
    //sum计算a-b的和
    int sum=0;
    
    //x作为换行标志
    //x初值为0,循环体每执行一次x+1,当x=5时,打印换行,并且对x赋值0,进行下一行打印
    int x=0;
    
    for(int i=a;i<=b;i++)
    {
        //每个数字占5个字符长度
        printf("%5d",i);
        
        //计算和
        sum+=i;
        
        x++;
        if(x==5)
        {
            printf("\n");
            x=0;
        }
    }
    
    //注意!!!这是一个测试点!!!
    //上边循环体打印的个数是5的倍数的时候
    //此时再次打印会在下一行
    //但是不是5的倍数的时候,没有打印换行
    //所以再次输出会在这一行的后面
    //所以我们要加一个判断
    //如果正好输出的个数是5的倍数,会在上面循环体的判断中打印换行,并且对x赋值0
    //如果不是5的倍数,x不管是几,肯定不会是0
    //小编觉得这和进制有点相同的意思
    if(x!=0)
        printf("\n");
    
    //打印a-b之间所有数之和
    printf("Sum = %d",sum);
    
    return 0;
}

 7-3 Cassels方程 (10 分)

Cassels方程是一个在数论界产生了巨大影响的不定方程:x2+y2+z2=3xyz。该方程有无穷多自然数解。

本题并不是要你求解这个方程,只是判断给定的一组 (x,y,z) 是不是这个方程的解。

输入格式:

输入在第一行给出一个不超过 10 的正整数 N,随后 N 行,每行给出 3 个正整数 0<x≤y≤z≤1000。

输出格式:

对于每一组输入,如果是一组解,就在一行中输出 Yes,否则输出 No

输入样例:

2
1 1 1
5 6 7

结尾无空行

输出样例:

Yes
No

结尾无空行

#include<stdio.h>
int main()
{
    //接收整数,同时也是下面循环体执行的次数
    int a;
    scanf("%d",&a);
    
    //循环判断
    for(int i=0;i<a;i++)
    {
        //接收每组解
        int b,c,d;
        scanf("%d %d %d",&b,&c,&d);
        
        //判断是否符合方程,打印的时候一定要加上换行
        //否则打印的时候成一大串,答案全部错误!!!
        if(b*b+c*c+d*d==b*c*d*3)
            printf("Yes\n");
        else
            printf("No\n");
    }
    
    return 0;
}

 7-4 降价提醒机器人 (10 分)

 小 T 想买一个玩具很久了,但价格有些高,他打算等便宜些再买。但天天盯着购物网站很麻烦,请你帮小 T 写一个降价提醒机器人,当玩具的当前价格比他设定的价格便宜时发出提醒。

输入格式:

输入第一行是两个正整数 N 和 M (1≤N≤100,0≤M≤1000),表示有 N 条价格记录,小 T 设置的价格为 M。

接下来 N 行,每行有一个实数 Pi​(−1000.0<Pi​<1000.0),表示一条价格记录。

输出格式:

对每一条比设定价格 M 便宜的价格记录 P,在一行中输出 On Sale! P,其中 P 输出到小数点后 1 位。

输入样例:

4 99
98.0
97.0
100.2
98.9

结尾无空行

输出样例:

On Sale! 98.0
On Sale! 97.0
On Sale! 98.9

结尾无空行

#include<stdio.h>
int main()
{
    //接收价格记录和价格整数
    //价格记录也是下面循环体执行的次数
    int a,b;
    scanf("%d %d",&a,&b);
    
    for(int i=0;i<a;i++)
    {
        //double的精度更高一些
        double c;
        scanf("%lf",&c);
        
        //注意输出一位小数
        if(c<b)
            printf("On Sale! %.1lf\n",c);
        //至于小编的输出是lf,因为我知道c是双精度类型
        //f也是可以的
        //为什么lf也可以,小编觉得是float除以一个整型会变成double型
        //程序员也不知道什么时候数据变成double型了,规定double的输出只能lf,最后的程序肯定会报错
        //输入的时候规定double必须用lf,因为你知道他就是double类型的,而在输出的时候你可能不知道他是double还是float
        //所以C语言开发者规定double输出可以用f
        //double的输出用lf也是小编的一个习惯吧
    }
    
    return 0;
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力敲代码啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值