青少年软件编程(C语言 二级) 2024-9 题目和答案

欢迎同学们提出自己的建议。

我自己开发了一个在线代码测评网站(OJ)ET答题,专注于青少年等级考试以及信奥赛相关比赛(CSP、NOIP),有需要的同学可以在网站首页添加我的练习方式,共同交流。

目录

1 火中取栗

2 垃圾分类

3 生成字母串

4 B是A的多少倍

5 机器人拼图


1 火中取栗

据法国诗人拉·封丹的寓言《猴子与猫》里说,猴子骗猫取火中的栗子,结果取出后被猴子吃了,猫却因此被烧掉了爪上的毛。

现在我们有 n 只炉子,每只炉子里烤着一些栗子。假设笨猫每次伸爪最多能从一只炉子里抓出 k 颗栗子,但会被烧掉 1 撮毛。问笨猫抓出所有的栗子最少要被烧掉多少撮毛?

时间限制:1000                内存限制:65536

输入

输入在第一行中给出 2 个正整数 n(≤ 100000)和 k(≤ 10),含义如题面所述。数字间以空格分隔。 随后一行给出 n 个不超过 1000 的正整数,其中第 i 个数字表示第 i 只炉子里烤的栗子的数量。

输出

在一行中输出笨猫抓出所有的栗子最少要被烧掉多少撮毛。

样例输入

5 2

3 4 8 1 15

样例输出

17

#include<iostream>
using namespace std;
int main(){
	int n,k,s=0;
	cin>>n>>k;
	for(int i=0;i<n;i++){
		int x;
		cin>>x;
		if(x%k==0) s+=x/k;
		else s+= x/k + 1;
	}
	cout<<s;
    return 0;
}

2 圾分类

据香港《南华早报》7月15日文章,上海严格的垃圾分类新规令不少居民抓狂。这催生出大量帮助找出正确分类答案的App和小程序。目前仅微信上就至少有280种与垃圾处理有关的App,在苹果应用商店也达130种。支付宝表示,已有60多家独立App开发商申请为该平台提供类似服务。

本题就请你现场实现一个简单的垃圾分类小助手。

时间限制:1000                内存限制:65536

输入

输入首先给出官方分类指南中每种物品的归属。在一行中给出一个正整数 N(≤ 100000),即物品数量;随后 N 行,每行给出一个物品名称(长度不超过 10 的、由小写英文字母和下划线组成的字符串)和该物品所属的分类(1 代表干垃圾、2 代表湿垃圾、3 代表可回收物、4 代表有害垃圾)。题目保证所有物品名称无重复。 随后每行给出一个查询物品的名称(格式与指南物品名称相同)。最后一行给出结束符 `#`,表示查询终止,这一行不需要查询。(查询的数量 ≤ 100000个)

输出

对每个查询的物品,在一行中给出其所属分类:`Gan laji` 代表干垃圾;`Shi laji` 代表湿垃圾;`Ke Hui Shou` 代表可回收物;`You Hai laji` 代表有害垃圾。如果查询的物品不在指南中,则输出 `?` 表示不知道。

样例输入

4

bao_zhi 3

dian_chi 4

dan_ke 2

bei_ke 1

dan_ke

dian_chi

ren_zha

bao_zhi

bei_ke

样例输出

Shi laji

You Hai laji

?

Ke Hui Shou

Gan laji

ps:这题题目有问题,说的‘#’结束输入,但是输入样例里面却没有一行是‘#’

ps:还有1个问题,题目的n的范围在100000以内,查询数量在100000以内,如果是最坏情况,顺序查找需要100000*100000=10000000000次,会超时,所以需要用快排或者归并排序之后,使用二分查找,时间复杂度O(n logn)。但是我不认为学到二级的小朋友会二分查找,更别说快速排序和归并排序。

#include<iostream>
using namespace std; 
struct node {	//垃圾结构体 
	string name;	//垃圾名字 
	int type;		//垃圾类型 
};
int main() {
	node laji[100005];
	int n;
	cin>>n; 
	for(int i=0; i<n; i++) {	//输入 
		cin>>laji[i].name>>laji[i].type;
	}
	string s;
	cin>>s;
	while(s!="#") {	//输入#结束 
		int i;
		for(i=0; i<n; i++) {
			if(laji[i].name==s){ //找到了 
				switch(laji[i].type){
					case 1: cout<<"Gan laji"<<endl; break;
					case 2: cout<<"Shi laji"<<endl; break;
					case 3: cout<<"Ke Hui Shou"<<endl; break;
					case 4: cout<<"You Hai laji"<<endl; break;
				}
				break; //结束当前查找	
			}
		}
		//正常结束,即为没找到 
		if(i==n) cout<<"?"<<endl;
		cin>>s; 
	}
    return 0;
}

3 成字母串

英语老师要求学生按照如下规则写一串字母:

- 如果写了某个大写字母,下一个就必须写同个字母的小写,或者写字母表中下一个字母的大写;
- 如果写了某个小写字母,下一个就必须写同个字母的大写,或者写字母表中前一个字母的小写。

例如 `aAaABCDdcbBC` 就是一个合法的字母串;而 `dEFfeFGhI` 就是非法的。

本题就请你编写程序,自动生成一个合法的字母串。

时间限制:1000                内存限制:65536

输入

输入在第一行给出一个不超过 10000 的正整数 N 和第一个字母。 随后一行给出一个由 `0` 和 `1` 组成的长度为 N 的字符串。这个串给出了字母串的生成规则:从第一个字母开始,如果对应的规则串字符是 `0`,则下一个字母应该生成当前字母的大/小写;如果是 `1` 则下一个字母应该生成当前字母的前/后一个字母。 注意:因为字母表中 `a` 没有前一个字母,`Z` 没有后一个字母,所以如果此时遇到 `1` 就忽略之。

输出

在一行中输出按规则生成的字母串。

样例输入

12 a

001011101101

样例输出

aAaABCDdcbBC

#include<iostream>
using namespace std; 
/*
大写字母,0:下一个就必须写同个字母的小写,1:字母表中下一个字母的大写;
小写字母,0:下一个就必须写同个字母的大写,1:字母表中前一个字母的小写。
*/
int main() {
	int n;
	char c;
	string rule; //变换规则 
	cin>>n>>c; 
	cin>>rule; 
	
	cout<<c;	//先原封不动输出第一个字符
	for(int i=0;i<n;i++){	//生成n次 
		if(rule[i]=='0'){	//规则0 
			if('A'<=c && c<='Z'){	//大写,转换为同个字母的小写
				c += 32; 
			} else {			//小写,转换为同个字母的大写
				c -= 32; 
			}			
		}
		else{ 			//规则1 
			if('A'<=c&& c<='Z'){	//大写,转换为下一个字母的大写
				if(c=='Z') continue; //没有,忽略 
				c += 1; 
			} else {			//小写,转换为前一个字母的小写
				if(c=='a') continue; //没有,忽略 
				c -= 1; 
			} 
		} 
		cout<<c;
	} 	
    return 0;
}

4 B是A的多少倍

设一个数 A 的最低 D 位形成的数是 ad。如果把 ad 截下来移到 A 的最高位前面,就形成了一个新的数 B。B 是 A 的多少倍?例如将 12345 的最低 2 位 45 截下来放到 123 的前面,就得到 45123,它约是 12345 的 3.66 倍。

时间限制:1000                内存限制:65536

输入

输入在一行中给出一个正整数 A(≤ 109)和要截取的位数 D。题目保证 D 不超过 A 的总位数。

输出

计算 B 是 A 的多少倍,输出小数点后 2 位。

样例输入

样例#1:

12345 2

样例#2:

12345 5

样例输出

样例#1:

3.66

样例#2:

1.00

#include<iostream>
#include<cmath>
using namespace std; 

int main() {
	int a,d,x,cnt=0;
	cin>>a>>d;
	x=a;
	while(x){	//cnt统计a有多少位 
		x/=10;
		cnt++; 
	}	
	
	int di=a%((int)pow(10,d)); //取后d位
	x = a/pow(10,d) + di*pow(10,cnt-d);	//转换后的数字
	
	float f=x*1.0/a; 	//计算倍数 
	printf("%.2f",f); //需要保留两位小数
    return 0;
}

5 机器人拼图


给定一块由 n × m 个格子组成的矩形拼图板,本题要求你根据给定的机械手移动指令集,将拼图中的碎片逐一放到指定位置。

机械手每次抓取一块碎片,都会在拼图板的左上角位置等待指令。一个指令集是由 0-4 这五个数字组成的字符串,每个数字代表的意义如下:

- 1:向右移动一格;
- 2:向下移动一格;
- 3:向左移动一格;
- 4:向上移动一格;
- 0:将碎片放置在当前位置,并结束这次任务。

如果指令要求机械手移动到拼图板边界外,机械手会无视这个指令。如果接收到指令 0 时,当前位置上已经有一块碎片放好了,机械手会扔掉手里的碎片,结束这次任务。

时间限制:5000                内存限制:65536

输入

输入第一行给出 2 个正整数 n 和 m(1 ≤ n,m ≤ 100),随后一共有 n × m 行,第 i 行给出编号为 i(i=1,... n×m)的碎片对应的指令集,每条指令集一定以唯一的 0 结尾。(总的指令操作步数不超超过107)

输出

输出 n 行,每行 m 个整数,为放置在对应位置上的碎片编号。如果该位置上没有碎片,则输出 0。一行中的数字间以 1 个空格分隔,行首位不得有多余空格。

样例输入

2 3

1120

21140

34120

0

110

21111340

样例输出

4 6 2

0 3 1

#include<iostream>
using namespace std; 

int main() {
	int n,m,a[105][105]={0};
	cin>>n>>m;
	
	for(int i=1;i<=n*m;i++){	//总共有n*m块碎片需要放置
		string cmd;
		cin>>cmd;
		int x=0,y=0; //初始位置 
		for(int j=0;j<cmd.length();j++){
			//识别指令 (注意防止超出边界)
			if(cmd[j]=='1' && y<m-1) y++;	
			else if(cmd[j]=='2' && x<n-1) x++; 
			else if(cmd[j]=='3' && y>0) y--; 
			else if(cmd[j]=='4' && x>0) x--;	
		}
		if(a[x][y]==0){ //该位置没用放过碎片 
			a[x][y] = i;
		} 
	} 
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cout<<a[i][j]<<' ';
		cout<<endl;
	} 
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值