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;
}