【入门2】分支结构 - 题单 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
1.
问题1到14略
输入格式
输入一个正整数,表示第几个问题。
输出格式
根据所输入的问题编号,输出对应问题的答案。
输入输出样例
输入 #1
2
输出 #1
6 4
说明/提示
请解决以下小学数学题。你可以提交答案,也可以写一个程序。
怎么看这题都是c++学cout输出的……每个答案都可以用cout。写个switch直接输出结果。
#include<stdio.h>
void question1()
{
printf("I love Luogu!");
}
void question2()
{
printf("6 4");
}
void question3()
{
printf("3\n12\n2");
}
void question4()
{
printf("%g",500/3.0);
}
void question5()
{
printf("15");
}
void question6()
{
printf("%g",sqrt(117));
}
void question7()
{
printf("110\n90\n0");
}
void question8()
{
printf("%g\n%g\n%g",2*5*3.141593,5*5*3.141593,4*5*5*5*3.141593/3);
}
void question9()
{
printf("22");
}
void question10()
{
printf("9");
}
void question11()
{
printf("%g",100/3.0);
}
void question12()
{
printf("13\nR");
}
void question13()
{
printf("16");
}
void question14()
{
printf("50");
}
int main()
{
int n;
scanf("%d", &n);
switch (n)
{
case 1: {question1(); break; }
case 2: {question2(); break; }
case 3: {question3(); break; }
case 4: {question4(); break; }
case 5: {question5(); break; }
case 6: {question6(); break; }
case 7: {question7(); break; }
case 8: {question8(); break; }
case 9: {question9(); break; }
case 10: {question10(); break; }
case 11: {question11(); break; }
case 12: {question12(); break; }
case 13: {question13(); break; }
case 14: {question14(); break; }
}
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
%g:在%f和%e输出中选择较短的类型,会自动保留六位有效数字(不是小数点后六位!!)
2.
题目描述
八尾勇喜欢吃苹果。她现在有 m(1≤m≤100)个苹果,吃完一个苹果需要花费 t(0≤t≤100)分钟,吃完一个后立刻开始吃下一个。现在时间过去了 s(1≤s≤10000)分钟,请问她还有几个完整的苹果?
输入格式
输入三个非负整数表示 m,t,s。
输出格式
输出一个整数表示答案。
输入输出样例
输入 #1
50 10 200
输出 #1
30
说明/提示
如果你出现了 RE,不如检查一下被零除?
有两个坑,一个是提示的t=0,另一个是问的剩下完整的苹果,所以一个苹果没吃完也要减去。都是加个if判断就行。
#include<stdio.h>
int main()
{
int m,t,s;
scanf("%d %d %d",&m,&t,&s);
if(t==0)
printf("0");
else
{
m-=s/t;
if(s%t)
m--;
if(m<0)
m=0;
printf("%d",m);
}
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
3.
题目描述
一些整数可能拥有以下的性质:
- 性质 1:是偶数;
- 性质 2:大于 4 且不大于 12。
小 A 喜欢这两个性质同时成立的整数;Uim 喜欢这至少符合其中一种性质的整数;八尾勇喜欢刚好有符合其中一个性质的整数;正妹喜欢不符合这两个性质的整数。现在给出一个整数 x,请问他们是否喜欢这个整数?
输入格式
输入一个整数 x(0≤x≤1000)
输出格式
输出这 4 个人是否喜欢这个数字,如果喜欢则输出 1
,否则输出 0
,用空格分隔。输出顺序为:小 A、Uim、八尾勇、正妹。
输入输出样例
输入 #1
12
输出 #1
1 1 0 0
写一个标记变量记录满足几种性质,再简单判断一下就行
#include<stdio.h>
int main()
{
int n,sign=0;
scanf("%d",&n);
if(n%2==0)
sign++;
if((n>4)&&(n<=12))
sign++;
if(sign==2)
printf("1 ");
else
printf("0 ");
if(sign>=1)
printf("1 ");
else
printf("0 ");
if(sign==1)
printf("1 ");
else
printf("0 ");
if(sign==0)
printf("1");
else
printf("0");
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
4.
题目描述
输入一个年份,判断这一年是否是闰年,如果是输出 1,否则输出 0。
输入格式
输入一个正整数 n,表示年份。
输出格式
输出一行。如果输入的年份是闰年则输出 1,否则输出 0。
输入输出样例
输入 #1
1926
输出 #1
0
输入 #2
1900
输出 #2
0
输入 #3
2000
输出 #3
1
输入 #4
1996
输出 #4
1
说明/提示
数据保证,1582≤n≤2020 且年份为自然数。
if else嵌套,从最特殊到最一般的顺序判断(400->100->4)
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
if((n%400)==0)
printf("1");
else if((n%100)==0)
printf("0");
else if(n%4)
printf("0");
else
printf("1");
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
5.
题目描述
八尾勇喜欢吃苹果。她今天吃掉了 x 个苹果。英语课上学到了 apple 这个词语,想用它来造句。如果她吃了 1 个苹果,就输出 Today, I ate 1 apple.
;如果她没有吃,那么就把 1 换成 0;如果她吃了不止一个苹果,别忘了 apple
这个单词后面要加上代表复数的 s
。你能帮她完成这个句子吗?
输入格式
输入一行一个自然数 x,表示吃掉的苹果数。
输出格式
根据题目要求输出。
输入输出样例
输入 #1
1
输出 #1
Today, I ate 1 apple.
输入 #2
3
输出 #2
Today, I ate 3 apples.
说明/提示
对于所有数据,0≤x≤100。
除了if我还能说什么呢,if秒了。
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
if(n<=1)
printf("Today, I ate %d apple.",n);
else
printf("Today, I ate %d apples.",n);
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
6.
题目描述
在洛谷上使用团队系统非常方便的添加自己的题目。如果在自己的电脑上配置题目和测试数据,每题需要花费时间 5 分钟;而在洛谷团队中上传私有题目,每题只需要花费 3 分钟,但是上传题目之前还需要一次性花费 11 分钟创建与配置团队。现在要配置 n 道题目,如果本地配置花费的总时间短,请输出 Local
,否则输出 Luogu
。
输入格式
输入一个正整数 n,表示需要配置的题目量。
输出格式
输出一行,一个字符串。如果本地配置花费的总时间短,请输出 Local
,否则输出 Luogu
。
输入输出样例
输入 #1
2
输出 #1
Local
输入 #2
50
输出 #2
Luogu
说明/提示
数据保证 1≤n≤100。
算出时间,判断大小。
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
if(5*n>11+3*n)
printf("Luogu");
else
printf("Local");
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
7.
题目描述
BMI 指数是国际上常用的衡量人体胖瘦程度的一个标准,其算法是 h/m^2,其中 m 是指体重(千克),h 是指身高(米)。不同体型范围与判定结果如下:
- 小于 18.5:体重过轻,输出
Underweight
; - 大于等于 18.5 且小于 24:正常体重,输出
Normal
; - 大于等于 24:肥胖,不仅要输出 BMI 值(使用
cout
的默认精度),然后换行,还要输出Overweight
;
现在给出体重和身高数据,需要根据 BMI 指数判断体型状态并输出对应的判断。
对于非 C++ 语言,在输出时,请四舍五入保留六位有效数字输出,如果小数部分存在后缀 0,不要输出后缀 0。
请注意,保留六位有效数字不是保留六位小数。例如 123.4567 应该输出为 123.457,5432.100 应该输出为 5432.1。
输入格式
共一行。
第一行,共 2 个浮点数,m,h,分别表示体重(单位为 kg),身高(单位为 m)。
输出格式
输出一行一个字符串,表示根据 BMI 的对应判断。特别地,对于 Overweight
情况的特别处理请参照题目所述。
输入输出样例
输入 #1
70 1.72
输出 #1
Normal
输入 #2
100 1.68
输出 #2
35.4308 Overweight
说明/提示
对于所有数据,40≤m≤120,1.4≤h≤2.0。m 和 h 的小数点后不超过三位。
先计算再判断。
#include<stdio.h>
int main()
{
float m,h,bmi;
scanf("%f %f",&m,&h);
bmi=(m/h)/h;
if(bmi<18.5)
printf("Underweight");
else if(bmi<24)
printf("Normal");
else
printf("%g\nOverweight",bmi);
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
8.
题目描述
给出三个整数a,b,c(0≤a,b,c≤100),要求把这三位整数从小到大排序。
输入格式
输入三个整数 a,b,c,以空格隔开。
输出格式
输出一行,三个整数,表示从小到大排序后的结果。
输入输出样例
输入 #1
1 14 5
输出 #1
1 5 14
输入 #2
2 2 2
输出 #2
2 2 2
直接判断符合哪种大小排序情况就行了。
#include<stdio.h>
int main()
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(a<b)
if(b<c)
printf("%d %d %d\n",a,b,c);
else if(a>c)
printf("%d %d %d\n",c,a,b);
else
printf("%d %d %d\n",a,c,b);
else if(a<c)
printf("%d %d %d\n",b,a,c);
else if(b>c)
printf("%d %d %d\n",c,b,a);
else
printf("%d %d %d\n",b,c,a);
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
9.
题目描述
输入年份和月份,输出这一年的这一月有多少天。需要考虑闰年。
输入格式
输入两个正整数,分别表示年份 y 和月数 m,以空格隔开。
输出格式
输出一行一个正整数,表示这个月有多少天。
输入输出样例
输入 #1
1926 8
输出 #1
31
输入 #2
2000 2
输出 #2
29
说明/提示
数据保证 1583≤y≤2020,1≤m≤12。
把闰年的判断(if)和月份的判断(switch)结合一下就好了,这里选择直接给二月基础天数(28)加上n,n赋值为0,判断为闰年时n赋值为1。
#include<stdio.h>
int main()
{
int n,m;
scanf("%d %d",&n,&m);
if((n%400)==0)
n=1;
else if((n%100)==0)
n=0;
else if(n%4)
n=0;
else
n=1;
switch(m)
{
case 2:printf("%d",28+n);break;
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:printf("31");break;
default:printf("30");break;
}
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
10.
题目描述
津津上初中了。妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。假设津津不会因为其它事不高兴,并且她的不高兴不会持续到第二天。请你帮忙检查一下津津下周的日程安排,看看下周她会不会不高兴;如果会的话,哪天最不高兴。
输入格式
输入包括 7 行数据,分别表示周一到周日的日程安排。每行包括两个小于 10 的非负整数,用空格隔开,分别表示津津在学校上课的时间和妈妈安排她上课的时间。
输出格式
一个数字。如果不会不高兴则输出 0,如果会则输出最不高兴的是周几(用 1,2,3,4,5,6,7 分别表示周一,周二,周三,周四,周五,周六,周日)。如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。
输入输出样例
输入 #1
5 3 6 2 7 2 5 3 5 4 0 4 0 6
输出 #1
3
说明/提示
NOIP2004 普及组第 1 题
- 2021-10-27:增加一组 hack 数据
- 2022-06-05:又增加一组 hack 数据
先把总上课时间算出来,再挨个判断是不是大于8或者目前最大的时间就行了。定义一个变量等于0作为标记和存储星期几,另一个变量存储标准8小时或者目前最大时间。
#include<stdio.h>
int main()
{
int n,m,date=0,max=8;
for(int i=1;i<=7;i++)
{
scanf("%d %d",&n,&m);
if((n+m)>max)
{
max=n+m;
date=i;
}
}
printf("%d",date);
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
11.NOIP2016 普及组 T1
题目描述
P 老师需要去商店买 n 支铅笔作为小朋友们参加 NOIP 的礼物。她发现商店一共有 3 种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起 见,P 老师决定只买同一种包装的铅笔。
商店不允许将铅笔的包装拆开,因此 P 老师可能需要购买超过 n 支铅笔才够给小朋友们发礼物。
现在 P 老师想知道,在商店每种包装的数量都足够的情况下,要买够至少 n 支铅笔最少需要花费多少钱。
输入格式
第一行包含一个正整数 n,表示需要的铅笔数量。
接下来三行,每行用 2 个正整数描述一种包装的铅笔:其中第 1 个整数表示这种包装内铅笔的数量,第 2 个整数表示这种包装的价格。
保证所有的 7 个数都是不超过 10000 的正整数。
输出格式
1 个整数,表示 P 老师最少需要花费的钱。
输入输出样例
输入 #1
57 2 2 50 30 30 27
输出 #1
54
输入 #2
9998 128 233 128 2333 128 666
输出 #2
18407
输入 #3
9999 101 1111 1 9999 1111 9999
输出 #3
89991
说明/提示
铅笔的三种包装分别是:
- 2 支装,价格为 2;
- 50 支装,价格为 30;
- 30 支装,价格为 27。
P老师需要购买至少 57 支铅笔。
如果她选择购买第一种包装,那么她需要购买 29 份,共计 2×29=58 支,需要花费的钱为 2×29=58。
实际上,P 老师会选择购买第三种包装,这样需要买 2 份。虽然最后买到的铅笔数量更多了,为 30×2=60 支,但花费却减少为 27×2=54,比第一种少。
对于第二种包装,虽然每支铅笔的价格是最低的,但要够发必须买 2 份,实际的花费达到了 30×2=60,因此 P 老师也不会选择。
所以最后输出的答案是 54。
【数据范围】
保证所有的 7 个数都是不超过 10000 的正整数。
【子任务】
子任务会给出部分测试数据的特点。如果你在解决题目中遇到了困难,可以尝试只解决一部分测试数据。
每个测试点的数据规模及特点如下表:
上表中“整倍数”的意义为:若为 K,表示对应数据所需要的铅笔数量 n —定是每种包装铅笔数量的整倍数(这意味着一定可以不用多买铅笔)。
于 2022 年 12 月 23 日新加 Hack 数据三组。
首先作为竞赛题,从计算思路过程到赋分点都已经写的非常详细了。先计算需要购买的最少包数,再计算价格并比较,输出最小的就行了。
#include<stdio.h>
int main()
{
int n,a,b,p,min;
scanf("%d",&n);
for(int i=0;i<3;i++)
{
scanf("%d %d",&a,&b);
p=b;
for(int j=1;(j*a)<n;j++)
{
p+=b;
}
if(i==0)
min=p;
if(p<min)
min=p;
}
printf("%d",min);
}
很蠢的代码,相当于自己算了n/a(进一法)。但是时间复杂度不会算。
#include<stdio.h>
int main()
{
int n,a,b,p,min;
scanf("%d",&n);
for(int i=0;i<3;i++)
{
scanf("%d %d",&a,&b);
p=((n+a-1)/a)*b;
if(i==0)
min=p;
if(p<min)
min=p;
}
printf("%d",min);
}
改了一下。用了一个自认为很天才的设计(自创的,难我天?),用((n+a-1)/a)实现了进一法的设计,比前面这坨玩意儿好使多了。时间复杂度O(1),空间复杂度O(1)。
12.
题目描述
给出三条线段 a,b,c 的长度,均是不大于 10000 的正整数。打算把这三条线段拼成一个三角形,它可以是什么三角形呢?
- 如果三条线段不能组成一个三角形,输出
Not triangle
; - 如果是直角三角形,输出
Right triangle
; - 如果是锐角三角形,输出
Acute triangle
; - 如果是钝角三角形,输出
Obtuse triangle
; - 如果是等腰三角形,输出
Isosceles triangle
; - 如果是等边三角形,输出
Equilateral triangle
。
如果这个三角形符合以上多个条件,请按以上顺序分别输出,并用换行符隔开。
输入格式
输入 3 个整数 a、b 和 c。
输出格式
输出若干行判定字符串。
输入输出样例
输入 #1
3 3 3
输出 #1
Acute triangle Isosceles triangle Equilateral triangle
输入 #2
3 4 5
输出 #2
Right triangle
输入 #3
6 10 6
输出 #3
Obtuse triangle Isosceles triangle
输入 #4
1 14 5
输出 #4
Not triangle
说明/提示
当两短边的平方和大于一长边的平方,说明是锐角三角形。
当两短边的平方和等于一长边的平方,说明是直角三角形。
当两短边的平方和小于一长边的平方,说明是钝角三角形。
简单的几个判断。
#include<stdio.h>
int main()
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if((a+b<=c)||(a+c<=b)||(b+c<=a))
printf("Not triangle");
else
{
if((a*a+b*b==c*c)||(b*b+c*c==a*a)||(a*a+c*c==b*b))
printf("Right triangle");
else if((a*a+b*b>c*c)&&(b*b+c*c>a*a)&&(a*a+c*c>b*b))
printf("Acute triangle");
else
printf("Obtuse triangle");
if ((a==b)||(b==c)||(a==c))
printf("\nIsosceles triangle");
if((a==b)&&(b==c))
printf("\nEquilateral triangle");
}
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
13.
题目描述
夏天到了,各家各户的用电量都增加了许多,相应的电费也交的更多了。小玉家今天收到了一份电费通知单。小玉看到上面写:据闽价电 [2006]27 号规定,月用电量在 150 千瓦时及以下部分按每千瓦时 0.4463 元执行,月用电量在 151∼400 千瓦时的部分按每千瓦时 0.4663 元执行,月用电量在 401 千瓦时及以上部分按每千瓦时 0.5663 元执行;小玉想自己验证一下,电费通知单上应交电费的数目到底是否正确呢。请编写一个程序,已知用电总计,根据电价规定,计算出应交的电费应该是多少。
输入格式
输入一个正整数,表示用电总计(单位以千瓦时计),不超过 10000。
输出格式
输出一个数,保留到小数点后 1 位(单位以元计,保留到小数点后 1 位)。
输入输出样例
输入 #1
267
输出 #1
121.5
if else的嵌套。
#include<stdio.h>
int main()
{
int n;
float sum=0;
scanf("%d",&n);
if(n<=150)
sum=n*0.4463;
else if(n<=400)
sum=150*0.4463+(n-150)*0.4663;
else
sum=150*0.4463+250*0.4663+(n-400)*0.5663;
printf("%.1f",sum);
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
14.
题目描述
有一只小鱼,它平日每天游泳 250 公里,周末休息(实行双休日),假设从周 x 开始算起,过了 n 天以后,小鱼一共累计游泳了多少公里呢?
输入格式
输入两个正整数 x,n,表示从周 x 算起,经过 n 天。
输出格式
输出一个整数,表示小鱼累计游泳了多少公里。
输入输出样例
输入 #1
3 10
输出 #1
2000
说明/提示
数据保证,1≤x≤7,1≤n≤10^6。
第i天加上初始周x对7取余的结果如果是6/0就是周末。用switch和if嵌套能写成时间复杂度O(1),但是可读性非常差。
#include<stdio.h>
int main()
{
int x,n,sum=0;
scanf("%d %d",&x,&n);
for(int i=0;i<n;i++)
{
if((i+x)%7==0||(i+x)%7==6);
else
sum+=250;
}
printf("%d",sum);
return 0;
}
时间复杂度O(n),空间复杂度O(1)。
15.
题目描述
输入一组勾股数 a,b,c(a≠b≠c),用分数格式输出其较小锐角的正弦值。(要求约分。)
输入格式
一行,包含三个正整数,即勾股数 a,b,c(无大小顺序)。
输出格式
一行,包含一个分数,即较小锐角的正弦值
输入输出样例
输入 #1
3 5 4
输出 #1
3/5
说明/提示
数据保证:a,b,c 为正整数且 ∈[1,10^9]∈[1,10^9]。
先找最大和最小值,再求其最大公约数,完成约分。
#include<stdio.h>
int main()
{
int a,b,c,min,max,n;
scanf("%d %d %d",&a,&b,&c);
if(a<b)
if(b<c)
min=a,max=c;
else if(a>c)
min=c,max=b;
else
min=a,max=b;
else if(a<c)
min=b,max=c;
else if(b>c)
min=c,max=a;
else
min=b,max=a;
for(int i=1;i<=min/2;i++)
{
if((min%i==0)&&(max%i==0))
n=i;
}
printf("%d/%d",min/n,max/n);
return 0;
}
时间复杂度O(n),空间复杂度O(1)。
16.NOIP 2005 普及组第一题
题目描述
陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 10 个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个 30 厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。
现在已知 10 个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。
输入格式
输入包括两行数据。第一行包含 10 个 100 到 200 之间(包括 100 和 200 )的整数(以厘米为单位)分别表示 10 个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。第二行只包括一个 100 到 120 之间(包含 100 和 120 )的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。
输出格式
输出包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。
输入输出样例
输入 #1
100 200 150 140 129 134 167 198 200 111 110
输出 #1
5
其实就是判断每个苹果的高度是不是比最大高度加板凳高度大。
#include<stdio.h>
int main()
{
int arr[10],n,sum=0;
for(int i=0;i<10;i++)
{
scanf("%d",&arr[i]);
}
scanf("%d",&n);
for(int i=0;i<10;i++)
{
if(arr[i]<=n+30)
sum++;
}
printf("%d",sum);
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
17. [COCI2006-2007#2]克罗地亚信息学比赛
题目描述
You will be given three integers A, B and C. The numbers will not be given in that exact order, but we do know that A is less than B and B less than C. In order to make for a more pleasant viewing, we want to rearrange them in the given order.
输入格式
The first line contains three positive integers A, B and C, not necessarily in that order. All three numbers will be less than or equal to 100. The second line contains three uppercase letters 'A', 'B' and 'C' (with no spaces between them) representing the desired order.
输出格式
Output the A, B and C in the desired order on a single line, separated by single spaces.
题意翻译
【题目描述】
三个整数分别为 A,B,C。这三个数字不会按照这样的顺序给你,但它们始终满足条件:A<B<C。为了看起来更加简洁明了,我们希望你可以按照给定的顺序重新排列它们。
【输入格式】
第一行包含三个正整数 A,B,C,不一定是按这个顺序。这三个数字都小于或等于 100100。第二行包含三个大写字母 A、B 和 C(它们之间没有空格)表示所需的顺序。
【输出格式】
在一行中输出 A,B 和 C,用一个 (空格)隔开。
感谢 @smartzzh 提供的翻译
输入输出样例
输入 #1
1 5 3 ABC
输出 #1
1 3 5
输入 #2
6 4 2 CAB
输出 #2
6 2 4
外国的竞赛题,有意思。其实判断完大小存进对应的ABC就行,再按输入的顺序依次输出。主要问题是为什么中间要getchar两次??明明vs里只要一次getchar,读取掉换行符就行了。
破案了,洛谷里换行使用的是\n\r两个符号
#include<stdio.h>
int main()
{
int a, b, c, A, B, C;
char n;
scanf("%d %d %d", &a, &b, &c);
if (a < b)
if (b < c)
A = a, C = c, B = b;
else if (a > c)
A = c, C = b, B = a;
else
A = a, C = b, B = c;
else if (a < c)
A = b, C = c, B = a;
else if (b > c)
A = c, C = a, B = b;
else
A = b, C = a, B = c;
getchar();
getchar();
for (int i = 0; i < 3; i++)
{
scanf("%c", &n);
if (i)
printf(" ");
switch (n)
{
case 65:printf("%d", A); break;
case 66:printf("%d", B); break;
case 67:printf("%d", C); break;
}
}
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
18.2008 普及组第一题
题目描述
每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 9 位数字、1 位识别码和 3 位分隔符,其规定格式如 x-xxx-xxxxx-x
,其中符号 -
就是分隔符(键盘上的减号),最后一位是识别码,例如 0-670-82162-4
就是一个标准的 ISBN 码。ISBN 码的首位数字表示书籍的出版语言,例如 0 代表英语;第一个分隔符 -
之后的三位数字代表出版社,例如 670 代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。
识别码的计算方法如下:
首位数字乘以 1 加上次位数字乘以 2 ……以此类推,用所得的结果 mod11,所得的余数即为识别码,如果余数为 10,则识别码为大写字母 X。例如 ISBN 号码 0-670-82162-4
中的识别码 44 是这样得到的:对 067082162
这 9 个数字,从左至右,分别乘以 1,2,…,9 再求和,即 0×1+6×2+……+2×9=158,然后取 158 mod 11 的结果 4 作为识别码。
你的任务是编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出 Right
;如果错误,则输出你认为是正确的 ISBN 号码。
输入格式
一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式要求)。
输出格式
一行,假如输入的 ISBN 号码的识别码正确,那么输出 Right
,否则,按照规定的格式,输出正确的 ISBN 号码(包括分隔符 -
)。
输入输出样例
输入 #1
0-670-82162-4
输出 #1
Right
输入 #2
0-670-82162-0
输出 #2
0-670-82162-4
先作为单个字符读取,再判断是不是数字。把9个数字都读出来运算余数并且取余结果为10时特别判断。
#include<stdio.h>
int main()
{
int sum = 0, sign = 1;
char arr[14];
arr[13] = 0;
for (int i = 1; i < 13; i++)
{
scanf("%c", &arr[i - 1]);
if ((arr[i - 1] >= 48) && (arr[i - 1] <= 57))
{
sum += sign * (arr[i - 1] - 48);
sign++;
}
}
scanf("%c", &arr[12]);
sum %= 11;
if (sum == 10)
if (arr[12] == 'X')
printf("Right");
else
{
arr[12] = 'X';
printf("%s", arr);
}
else
if (sum == (arr[12] - 48))
printf("Right");
else
{
arr[12] = (sum + 48);
printf("%s", arr);
}
return 0;
}
时间复杂度O(1),空间复杂度O(1)。
19.
树状数组(二进制下标树,Binary Index Tree, BIT)
基于二叉树的算法,核心在于lowbit计算,确实很神奇。
*lowbit:取一个二进制数右起第一个1及后面所有0的值。
二叉树的所有父结点序号都可以通过子结点序号加上自身lowbit值得到,而一个子结点序号减去自身lowbit值可以得到同一父结点更低序号的子结点。由此原理进行修改与查询操作。
将数组修改与查询的时间复杂度统一至O(logn)的算法,无法进行复杂的操作,优点在于编写方便简单(因为不用递归,而是改用二进制计算的思想)。
#include<stdio.h>
int lowbit(int n)
{
int lowbit;
lowbit = n & (-n);
return lowbit;
}
void buildtree(int arr[], int tree[], int n)
{
for (int i = 1; i <= n; i++)
{
tree[i-1] += arr[i-1];
if ((i + lowbit(i)) <= n)
tree[i-1 + lowbit(i)] += tree[i-1];
}
}
void update(int arr[], int tree[], int n, int v, int value)
{
value = value - arr[v-1];
while (v <= n)
{
tree[v-1] += value;
v = v + lowbit(v);
}
}
int query(int tree[], int n)
{
int sum=0;
do
{
sum += tree[n - 1];
n = n - lowbit(n);
} while (n > 0);
return sum;
}
int queryn(int tree[], int s,int n)
{
int sum;
sum = query(tree, n) - query(tree, s-1);
return sum;
}
int main()
{
int tree[100] = { 0 };
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
buildtree(arr, tree, 10);
update(arr, tree, 10, 10, 10);
for (int i = 0; i < 10; i++)
{
printf("%d\n", tree[i]);
}
printf("%d\n",query(tree, 10));
printf("%d\n", queryn(tree, 9,10));
return 0;
}
20.
快速排序算法
#include<stdio.h>
#include<time.h>
void swap(int *a, int *b)
{
if (a != b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
}
int sort(int arr[],int *s,int *n)
{
if (n == (s + 1))
{
if (*s > *n)
swap(s, n);
return 0;
}
int *star = s;
int *sign = n;
int k = 0;
while (1)
{
while (*s <= *sign)
{
if (s == n)
{
swap(s, sign);
if ((s - 1) >= star)
sort(arr, star, s - 1);
if ((s + 1) <= sign)
sort(arr, s + 1, sign);
k = 1;
break;
}
s++;
}
if (k) break;
while (*n >= *sign)
{
if (s == n)
{
swap(s, sign);
if ((s-1)>=star)
sort(arr, star, s - 1);
if ((s+1)<=sign)
sort(arr, s + 1, sign);
k = 1;
break;
}
n--;
}
if (k) break;
swap(s, n);
}
return 0;
}
int main()
{
clock_t start, finish;
double duration;
start = clock();
for (int p = 0; p < 10000; p++)
{
int arr[100] = { 2,4,1,6,9,4,6,3,2,5,4,7,4,6,8,3,2,6,2,6,2,6,5,8,9,4,3,6,7,3,3,6,7,3,3,67,3,5,3,5,3,56,35,2,1,4,7,346,8,52,2,4,1,6,9,4,6,3,2,5,4,7,4,6,8,3,2,6,2,6,2,6,5,8,9,4,3,6,7,3,3,6,7,3,3,67,3,5,3,5,3,56,35,2,1,4,7,346,8,52 };
sort(arr, arr, &arr[99]);
for (int i = 0; i < 99; i++)
printf("%d ", arr[i]);
}
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC/10000;
printf("%lf", duration);
return 0;
}
自己按照算法原理写的代码,效率很差,不过能跑。加上了平均运行时间的计算。
#include<time.h>
clock_t start, finish;
double duration;
start = clock();
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC/10000;
printf("%lf", duration);