本文结合PTA专项练习带领读者掌握选择结构,刷题为主注释为辅,在代码中理解思路,其它不做过多叙述。
7-1 比较大小
本题要求将输入的任意3个整数从小到大输出。
输入格式:
输入在一行中给出3个整数,其间以空格分隔。
输出格式:
在一行中将3个整数从小到大输出,其间以“->”相连。
输入样例:
4 2 8
输出样例:
2->4->8
#include <stdio.h> int main() { int a,b,c; scanf("%d %d %d",&a,&b,&c); int max=a>b?a:b; int min=a<b?a:b; if(c>max) { printf("%d->%d->%d",min,max,c); } else if(c<min) { printf("%d->%d->%d",c,min,max); } else { printf("%d->%d->%d",min,c,max); } }
7-2 三天打鱼两天晒网
中国有句俗语叫“三天打鱼两天晒网”。假设某人从某天起,开始“三天打鱼两天晒网”,问这个人在以后的第N天中是“打鱼”还是“晒网”?
输入格式:
输入在一行中给出一个不超过1000的正整数N。
输出格式:
在一行中输出此人在第N天中是“Fishing”(即“打鱼”)还是“Drying”(即“晒网”),并且输出“in day N”。
输入样例1:
103
输出样例1:
Fishing in day 103
输入样例2:
34
输出样例2:
Drying in day 34
#include <stdio.h> int main() { int n; scanf("%d",&n); if(n%5==1||n%5==2||n%5==3) { printf("Fishing in day %d",n); } else { printf("Drying in day %d",n); } }
7-3 21选择-个人所得税
众所周知,hygg 非常善于 make money! 现在给定 hygg 赚的钱数,以及如下的个人所得税表。请输出 hygg 应交的税。
级数 | 全年应纳税所得额 | 税率(%) |
1 | 不超过36000元的 | 3 |
2 | 超过36000元至144000元的部分 | 10 |
3 | 超过144000元至300000元的部分 | 20 |
4 | 超过300000元至420000元的部分 | 25 |
5 | 超过420000元至660000元的部分 | 30 |
6 | 超过660000元至960000元的部分 | 35 |
7 | 超过960000元的部分 | 45 |
输入格式:
一个实数 n(0 ≤ n ≤ 109 ) ,表示 hygg 赚的钱数。
输出格式:
一个实数,表示 hygg 应交的税(四舍五入到分)。
输入样例:
20000.00
输出样例:
600.00
#include <stdio.h> int main() { double n; double s; scanf("%lf",&n); if(n<=36000) { s=n*0.03; } else if(n<=144000) { s=36000*0.03+(n-36000)*0.1; } else if(n<=300000) { s=36000*0.03+(144000-36000)*0.1+(-144000+n)*0.2; } else if(n<=420000) { s=36000*0.03+(144000-36000)*0.1+(300000-144000)*0.2+(-300000+n)*0.25; } else if(n<=660000) { s=36000*0.03+(144000-36000)*0.1+(300000-144000)*0.2+(420000-300000)*0.25+(-420000+n)*0.3; } else if(n<=960000) { s=36000*0.03+(144000-36000)*0.1+(300000-144000)*0.2+(420000-300000)*0.25+(660000-420000)*0.3+(-660000+n)*0.35; } else{ s=36000*0.03+(144000-36000)*0.1+(300000-144000)*0.2+(420000-300000)*0.25+(660000-420000)*0.3+(-660000+960000)*0.35+(-960000+n)*0.45; } printf("%.2f",s); }
7-4 计算天数
本题要求编写程序计算某年某月某日是该年中的第几天。
输入格式:
输入在一行中按照格式“yyyy/mm/dd”(即“年/月/日”)给出日期。注意:闰年的判别条件是该年年份能被4整除但不能被100整除、或者能被400整除。闰年的2月有29天。
输出格式:
在一行输出日期是该年中的第几天。
输入样例1:
2009/03/02
输出样例1:
61
输入样例2:
2000/03/02
输出样例2:
62
#include <stdio.h> int main() { int year,month,day,sum; scanf("%d/%d/%d",&year,&month,&day); int a=0; switch(month) // 先计算某月以前月份的总天数 { case 1:sum=0;break; case 2:sum=31;break; case 3:sum=59;break; case 4:sum=90;break; case 5:sum=120;break; case 6:sum=151;break; case 7:sum=181;break; case 8:sum=212;break; case 9:sum=243;break; case 10:sum=273;break; case 11:sum=304;break; case 12:sum=334;break; } sum=sum+day; if(year%400==0||(year%4==0&&year%100!=0)) { a=1; } if(a==1&&month>2) { //如果是闰年且月份大于等于3,则总天数加一 sum=sum+1; } printf("%d",sum); }
7-5 21选择-手表调整
我们常常认为,新闻联播开始时,是北京时间 19 : 00 : 00 。
chy 在今天新闻联播开始时,发现手表的时间是 hh : mm : ss 的形式,请问他的手表快了或慢了多少?
我们认为,当手表时间不快于当前时间 12 小时时,手表是快了;否则我们认为手表慢了。
输入格式:
一行三个整数,严格按照 hh : mm : tt 的形式。
输出格式:
当手表快了时,严格按 +hh : mm : tt 的形式输出快的时间
当手表慢了时,严格按 −hh : mm : tt 的形式输出慢的时间。
输入样例:
03:59:59
输出样例:
+08:59:59
#include <stdio.h> int main() { int a,b,c; scanf("%d:%d:%d",&a,&b,&c); //快的情况 if(a>=19&&a<=24) { printf("+%02d:%02d:%02d",a-19,b,c); } if(a>=0&&a<7) { printf("+%02d:%02d:%02d",24-19+a,b,c); } //慢的情况 if((a>=7&&a<19)&&b!=00&&c!=00) //b、c都不是00 { printf("-%02d:%02d:%02d",19-a-1,60-b-1,60-c); } if((a>=7&&a<19)&&b!=00&&c==00) {//c是00 printf("-%02d:%02d:%02d",19-a-1,60-b,00); } if((a>=7&&a<19)&&b==00&&c!=00) {//b是00 printf("-%02d:%02d:%02d",19-a-1,59,60-c); } if((a>7&&a<19)&&b==00&&c==00) {//b、c都是00 printf("-%02d:%02d:%02d",19-a,00,00); } }
7-6 21选择-最短完成时间
T6N 在参加一场比赛。对于一道题,他可以花 7 分钟去洗手间把他做出来再回到赛场。T6N 也可以用大招【意念感知】获取别人的代码,开大招需要不间断引导 15 分钟,但开完大招后对于一道题他只需要 5 分钟就可以感应到别人的代码并通过。
简而言之,T6N 可以在任何时刻开大招,大招需要不间断引导 15 分钟(期间不能做任何事)。只要之前开过大招,T6N 通过一道题只要 5 分钟;否则就需要 7 分钟。
现在有 n 道题要通过,T6N 希望你判断一下他通过所有题目的最短时间。
输入格式:
输入仅一行,包含一个正整数 n (n ≤ 15)。
输出格式:
输出仅一行,包含一个正整数,表示通过所有题目的最短时间。
输入样例:
9
输出样例:
60
#include <stdio.h> int main() { int n; scanf("%d",&n); int a=n*7; int b=15+n*5; if(a>b) { printf("%d",b); } else printf("%d",a); }
7-7 日K蜡烛图
股票价格涨跌趋势,常用蜡烛图技术中的K线图来表示,分为按日的日K线、按周的周K线、按月的月K线等。以日K线为例,每天股票价格从开盘到收盘走完一天,对应一根蜡烛小图,要表示四个价格:开盘价格Open(早上刚刚开始开盘买卖成交的第1笔价格)、收盘价格Close(下午收盘时最后一笔成交的价格)、中间的最高价High和最低价Low。
如果Close<Open,表示为“BW-Solid”(即“实心蓝白蜡烛”);如果Close>Open,表示为“R-Hollow”(即“空心红蜡烛”);如果Open等于Close,则为“R-Cross”(即“十字红蜡烛”)。如果Low比Open和Close低,称为“Lower Shadow”(即“有下影线”),如果High比Open和Close高,称为“Upper Shadow”(即“有上影线”)。请编程序,根据给定的四个价格组合,判断当日的蜡烛是一根什么样的蜡烛。
输入格式:
输入在一行中给出4个正实数,分别对应Open、High、Low、Close,其间以空格分隔。
输出格式:
在一行中输出日K蜡烛的类型。如果有上、下影线,则在类型后加上with 影线类型
。如果两种影线都有,则输出with Lower Shadow and Upper Shadow
。
输入样例1:
5.110 5.250 5.100 5.105
输出样例1:
BW-Solid with Lower Shadow and Upper Shadow
输入样例2:
5.110 5.110 5.110 5.110
输出样例2:
R-Cross
输入样例3:
5.110 5.125 5.112 5.126
输出样例3:
R-Hollow
#include <stdio.h> int main() { double open,high,low,close; scanf("%lf %lf %lf %lf",&open,&high,&low,&close); if(close<open) { if(low<close&&high<=open) { printf("BW-Solid with Lower Shadow"); } else if(low>=close&&high>open) { printf("BW-Solid with Upper Shadow"); } else if(low<close&&high>open) { printf("BW-Solid with Lower Shadow and Upper Shadow"); } else { printf("BW-Solid"); } } if(close>open) { if(low<open&&high<=close) { printf("R-Hollow with Lower Shadow"); } else if(high>close&&low>=open) { printf("R-Hollow with Upper Shadow"); } else if(low<open&&high>close) { printf("R-Hollow with Lower Shadow and Upper Shadow"); } else { printf("R-Hollow"); } } if(close==open) { if(low<close&&high<=open) { printf("R-Cross with Lower Shadow"); } else if(low>=close&&high>open) { printf("R-Cross with Upper Shadow"); } else if(low<close&&high>open) { printf("R-Cross Lower Shadow and Upper Shadow"); } else { printf("R-Cross"); } } }
7-8 三角形判断
给定平面上任意三个点的坐标(x1,y1)、(x2,y2)、(x3,y3),检验它们能否构成三角形。
输入格式:
输入在一行中顺序给出六个[−100,100]范围内的数字,即三个点的坐标x1、y1、x2、y2、x3、y3。
输出格式:
若这3个点不能构成三角形,则在一行中输出“Impossible”;若可以,则在一行中输出该三角形的周长和面积,格式为“L = 周长, A = 面积”,输出到小数点后2位。
输入样例1:
4 5 6 9 7 8
输出样例1:
L = 10.13, A = 3.00
输入样例2:
4 6 8 12 12 18
输出样例2:
Impossible
#include <stdio.h> #include <math.h> int main() { double x1, y1, x2, y2, x3, y3; scanf("%lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3); double ab = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); double ac = sqrt((x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3)); double bc = sqrt((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2)); if (ab != 0 && ac != 0 && bc != 0 && ab + bc > ac && ab + ac > bc && ac + bc > ab) { //三边均不为0且任意两边之和都大于第三边 printf("L = %.2f,", ab + ac + bc); double p = (ab + ac + bc) / 2.0; double s = sqrt(p * (p - ab) * (p - bc) * (p - ac)); printf(" A = %.2f", s); } else { printf("Impossible"); } }
7-9 求一元二次方程的根
本题目要求一元二次方程ax2+bx+c=0的根,结果保留2位小数。(注意:0.00会在gcc下被输出为-0.00,需要做特殊处理,输出正确的0.00。)
输入格式:
输入在一行中给出3个浮点系数a、b、c,中间用空格分开。
输出格式:
根据系数情况,输出不同结果:
1)如果方程有两个不相等的实数根,则每行输出一个根,先大后小;
2)如果方程有两个不相等复数根,则每行按照格式“实部+虚部i”输出一个根,先输出虚部为正的,后输出虚部为负的;
3)如果方程只有一个根,则直接输出此根;
4)如果系数都为0,则输出"Zero Equation";
5)如果a和b为0,c不为0,则输出"Not An Equation"。
输入样例1:
2.1 8.9 3.5
输出样例1:
-0.44 -3.80
输入样例2:
1 2 3
输出样例2:
-1.00+1.41i -1.00-1.41i
输入样例3:
0 2 4
输出样例3:
-2.00
输入样例4:
0 0 0
输出样例4:
Zero Equation
输入样例5:
0 0 1
输出样例5:
Not An Equation
#include <stdio.h> #include <math.h> int main() { double a, b, c; scanf("%lf %lf %lf", &a, &b, &c); double delta = b * b - 4.0 * a * c; // 判别式 if (a != 0 && delta > 0.00) { // 两个不相等的实数根 double x1 = 1.0 * (-b + sqrt(delta)) / (2.0 * a); double x2 = 1.0 * (-b - sqrt(delta)) / (2.0 * a); if (x1 != 0.00) printf("%.2f\n", x1); else printf("0.00\n"); if (x2 != 0.00) printf("%.2f\n", x2); else printf("0.00\n"); } else if (a != 0 && delta == 0) { // 有一个实数根 double x = -b * 1.0 / (2.0 * a); if (x != 0.00) printf("%.2f\n", x); else printf("0.00\n"); } else if (a != 0 && delta < 0) { // 两个共轭复数根 double p = -b * 1.0 / (2.0 * a); double q = 1.0 * sqrt(-delta) / (2.0 * a); if (p == 0.00) { printf("0.00+%.2fi\n", q); printf("0.00-%.2fi", q); } else { printf("%.2f+%.2fi\n", p, q); printf("%.2f-%.2fi", p, q); } } else if (a == 0 && b != 0) { // 一元一次方程 if (c == 0) { printf("0.00"); } else { double x = -c / b; printf("%.2f", x); } } else if (a == 0 && b == 0) { // 方程无意义 if (c == 0) { printf("Zero Equation"); } else printf("Not An Equation"); } return 0; }