洛谷 CCF GESP C++ 三级上机题 部分题目题解

       我下个月就要考GESP C++三级了,所以,为了加深我做出来的题目的印象,我写了这篇文章,希望各位宝子们也能学习参考这些题解。

       在文章正式开始前,我先把洛谷 CCF GESP C++ 三级上机题的题目传送门给大家,方便边学习边打代码。

       CCF GESP C++ 三级上机题 - 题单 - 洛谷

       那么接下来,题解正式开始。

B3848 [GESP样题 三级] 逛商场

题目传送门:[GESP样题 三级] 逛商场 - 洛谷

题目描述

小明是个不太有计划的孩子。这不,刚到手的零花钱,就全部拿着逛商场去了。

小明的原则很简单,见到想买的物品,只要能买得起,就一定会买下来之后才会继续往前走;如果买不起就直接跳过。

一天下来,小明到底买了多少物品呢?

输入格式

输入共 3 行:

第一行是一个整数 N,表示商场中共有 N 种小明想买的物品(1≤N≤100);

第二行共有 N 个整数,分别表示小明先后见到想买的物品的价格;

第三行是一个整数 X,表示开始时小明共有 X 元零花钱。

输出格式

输出 1 行,包含一个整数,表示小明买到的物品数。

输入输出样例

输入 #1复制

6
7 5 9 10 7 4
30

输出 #1复制

4

说明/提示

数据范围:

对于 100% 的数据满足 1≤N≤100 且 0≤100000。

对于这道题呢,主要的解题思路就是循环遍历,判断如果买得起,就减去东西的价格,否则就continue。最后输出减掉的次数。下面给出AC代码:

#include<iostream>
using namespace std;
int main(){
	int n,x,sum=0;
	cin>>n;
	int a[100005];
	for(int i=1;i<=n;i++) cin>>a[i];
	cin>>x;
	for(int i=1;i<=n;i++){
		if(x>=a[i]){
			x-=a[i];
			sum++;
		}
		else if(x<a[i]) continue;
	}
	cout<<sum;
	return 0;
}

B3842 [GESP202306 三级] 春游

题目传送门:[GESP202306 三级] 春游 - 洛谷

题目描述

老师带领同学们春游。已知班上有 N 位同学,每位同学有从 0 到 N−1 的唯一编号。到了集合时间,老师确认是否所有同学都到达了集合地点,就让同学们报出自己的编号。到达的同学都会报出自己的编号,不会报出别人的编号,但有的同学很顽皮,会多次报出。你能帮老师找出有哪些同学没有到达吗 ?

输入格式

输入包含 2 行。第一行包含两个整数 N 和 M,表示班级有 N 位同学,同学们共有 M 次报出编号。约定 2≤N,M≤1000。
第二行包含 M 个整数,分别为 M 次报出的编号。约定所有编号是小于 N 的非负整数。

输出格式

输出一行。如果所有同学都到达,则输出 N;否则由小到大输出所有未到达的同学编号,空格分隔。

输入输出样例

输入 #1复制

3 3
0 2 1

输出 #1复制

3

输入 #2复制

3 5
0 0 0 0 0

输出 #2复制

1 2

这道题更简单了吧,就是先设一个bool数组,然后输入一个,bool数组相应编号的元素就设为1(代表已经到达)。最后循环判断数组中哪个元素为0,计数器就加1。输出计数器。下面是AC代码:

#include<iostream>
using namespace std;
int main(void)
{
	int n,m,sum=0;
	cin>>n>>m;
	int l;
	bool a[100005];
	for(int i=0;i<m;i++){
		cin>>l;
		a[l]=1;//1代表已经到达
	}
	for(int i=0;i<n;i++){
		if(a[i]==0) cout<<i<<' ';//判断没有到达的同学 
		else sum++;//计算到达的同学个数 
	}
	if(sum==n) cout<<n;//如果同学们已经全部到达,那么就输出同学的个数 
	return 0;
}

B3867 [GESP202309 三级] 小杨的储蓄

题目传送门:[GESP202309 三级] 小杨的储蓄 - 洛谷

题目描述

小杨共有 N 个储蓄罐,编号从 0 到 N−1。从第 1 天开始,小杨每天都会往存钱罐里存钱。具体来说,第 i 天他会挑选一个存钱罐 ai​,并存入 i 元钱。过了 D 天后,他已经忘记每个储蓄罐里都存了多少钱了,你能帮帮他吗?

输入格式

输入 2 行,第一行两个整数 N,D;第二行 D 个整数,其中第 i 个整数为 ai(保证 0≤ai≤N−1)。

每行的各个整数之间用单个空格分隔。

保证 1≤N≤1,000;1≤D≤1,000。

输出格式

输出 N 个用单个空格隔开的整数,其中第 i 个整数表示编号为 i−1 的存钱罐中有多少钱(i=1,⋯ ,N)。

输入输出样例

输入 #1复制

2 3
0 1 0

输出 #1复制

4 2

输入 #2复制

3 5
0 0 0 2 0

输出 #2复制

11 0 4

说明/提示

样例解释 1:

小杨在第 1 天、第 2 天、第 3 天分别向 0 号、 1 号、 0 号存钱罐存了 1 元钱、 2 元钱、 3 元钱,因此 0 号存钱罐有 1+3=4 元钱,而 1 号存钱罐有 2 元钱。

这道题跟上一道题差不多,也是用同样的思路。这里我不多说了,直接给出AC代码:

#include<iostream>
using namespace std;
int main(){
	int n,d,l;
	cin>>n>>d;
	int a[100005];
	for(int i=1;i<=d;i++){
		cin>>l;
		a[l]+=i;
	}
	for(int i=0;i<n;i++){
		cout<<a[i]<<' ';
	}
	return 0;
}

B3868 [GESP202309 三级] 进制判断 

题目传送门:[GESP202309 三级] 进制判断 - 洛谷

题目描述

N 进制数指的是逢 N 进一的计数制。例如,人们日常生活中大多使用十进制计数,而计算机底层则一般使用二进制。除此之外,八进制和十六进制在一些场合也是常用的计数制(十六进制中,一般使用字母 A 至 F 表示十至十五)。

现在有N个数,请你分别判断他们是否可能是二进制、八进制、十进制、十六进制。例如,15A6F 就只可能是十六进制,而 1011 则是四种进制皆有可能。

输入格式

输入的第一行为一个十进制表示的整数 N。接下来 N 行,每行一个字符串,表示需要判断的数。保证所有字符串均由数字和大写字母组成,可能以 0 开头。保证不会出现空行。

保证 1≤N≤1000,保证所有字符串长度不超过 10。

输出格式

输出 N 行,每行 4 个数,用空格隔开,分别表示给定的字符串是否可能表示一个二进制数、八进制数、十进制数、十六进制数。使用 1 表示可能,使用 0 表示不可能。

例如,对于只可能是十六进制数的 15A6F,就需要输出 0 0 0 1;而对于四者皆有可能的 1011,则需要输出 1 1 1 1

输入输出样例

输入 #1复制

2
15A6F
1011

输出 #1复制

0 0 0 1
1 1 1 1

输入 #2复制

4
1234567
12345678
FF
GG

输出 #2复制

0 1 1 1
0 0 1 1
0 0 0 1
0 0 0 0

这道题不算很难,用点小技巧就过了。就是初始化一个bool数组,表示四者皆有可能。再循环判断非二进制、八进制、十进制、十六进制的情况,如果有,可能的进制的元素就设为0。再输出是否是0或者1,注意换行。下面给出AC代码:

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	string s;
	for(int i=1;i<=n;i++){
		cin>>s;
		bool a[4]={1,1,1,1};
		for(int j=0;j<s.length();j++){
			if(s[j]>'1') a[0]=0; //非二进制 
			if(s[j]>'7') a[1]=0; //非八进制
			if(s[j]>'9') a[2]=0; //非十进制
			if(s[j]>'F') a[3]=0; //非十六进制 
		}
		cout<<a[0]<<' '<<a[1]<<' '<<a[2]<<' '<<a[3]<<'\n';
	}
	return 0;
}

B3926 [GESP202312 三级] 单位转换

题目传送门:[GESP202312 三级] 单位转换 - 洛谷

小杨这周的数学作业是做单位转换,喜欢编程的小杨决定编程帮他解决这些问题。

小杨只学了长度单位和重量单位,具体来说:

  • 长度单位包括千米(km)、米(m)、毫米(mm),它们之间的关系是:1km=1000m=1000000mm。

  • 重量单位包括千克(kg)、克(g)、毫克(mg),它们之间的关系是:1kg=1000g=1000000mg。

小杨的作业只涉及将更大的单位转换为更小的单位,也就是说,小杨的作业只会包含如下题型:米转换为毫米,千米转换为毫米,千米转换为米,克转换为毫克,千克转换为毫克,千克转换为克。

现在,请你帮忙完成单位转换的程序。

输入格式

输入的第一行为一个整数,表示题目数量。

接下来 N 行,每行一个字符串,表示转换单位的题目,格式为 x 单位 1=? 单位 2。其中,x 为一个不超过 1000 的非负整数, 单位 1 和 单位 2 分别为两个单位的英文缩写,保证它们都是长度单位或都是重量单位,且 单位 1 比 单位 2 更大。

例如,如果题目需要你将 1km 转换为 mm,则输入为 1 km = ? mm

保证 1≤N≤1000。

输出格式

输出 N 行,依次输出所有题目的答案,输出时,只需要将输入中的 ? 代入答案,其余部分一字不差地输出即可。由于小杨的题目只涉及将更大的单位转换为更小的单位,并且输入的 x 是整数,因此答案一定也是整数。

例如,如果题目需要你将 1km 转换为 mm,则输入为 1 km = ? mm。则你需要输出 1 km = 1000000 mm

输入输出样例

输入 #1复制

2
1 km = ? mm
1 m = ? mm

输出 #1复制

1 km = 1000000 mm
1 m = 1000 mm

输入 #2复制

5
100 m = ? mm
1000 km = ? m
20 kg = ? g
200 g = ? mg
0 kg = ? mg

输出 #2复制

100 m = 100000 mm
1000 km = 1000000 m
20 kg = 20000 g
200 g = 200000 mg
0 kg = 0 mg

这道题题目中说了“小杨的作业只涉及将更大的单位转换为更小的单位,也就是说,小杨的作业只会包含如下题型:米转换为毫米,千米转换为毫米,千米转换为米,克转换为毫克,千克转换为毫克,千克转换为克。”所以,我们可以把字符串当做单位,如果字符串1的长度为1(代表此单位可能是m、g),把他们转换成小单位,就只能是mm或者是mg。它们的进率为1000,直接输出数字1*1000。否则进率就是1000000,输出数字1*1000000。下面是AC代码:

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	while(n--){
		int a;
		string b,c;
		cin>>a>>b>>c>>c>>c;
		if(b.length()==1||c.length()==1) cout<<a<<" "<<b<<" = "<<a*1000<<" "<<c<<"\n";
		else cout<<a<<" "<<b<<" = "<<a*1000000<<" "<<c<<'\n';
	}
	return 0;
}

B3956 [GESP202403 三级] 字母求和

题目传送门:[GESP202403 三级] 字母求和 - 洛谷

题目描述

小杨同学发明了一种新型密码,对于每一个小写英文字母,该小写字母代表了一个正整数,即该字母在字母顺序中的位置,例如字母 a 代表了正整数 1,字母 b 代表了正整数 2;对于每一个大写英文字母,该大写字母代表了一个负整数,即该字母的 ASCII 码的相反数,例如字母 A 代表了负整数 −65。小杨同学利用这种放缩对一个整数进行了加密并得到了一个由大写字母和小写字母组成的字符串,该字符串中每个字母所代表数字的总和即为加密前的整数,例如 aAc 对应的加密前的整数为 1+(−65)+3=−61。

对于给定的字符串,请你计算出它对应的加密前的整数是多少。

输入格式

第一行一个正整数 n,表示字符串中字母的个数。
第二行一个由大写字母和小写字母的字符串 T,代表加密后得到的字符串。

输出格式

输出一行一个整数,代表加密前的整数。

输入输出样例

输入 #1复制

3
aAc

输出 #1复制

-61

说明/提示

对全部的测试数据,保证 1≤n≤pow(10,5)。

这道题太easy了,只需要轻微判断一下就行了,如果是负数就加上它的绝对值(但我这里不写绝对值),否则直接加上它的编号,就是编号要设定一下,可能会打到手废,这里建议直接复制。下面是AC代码:

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	string s;
	cin>>s;
	int sum=0;
	for(int i=0;i<n;i++){
		if(s[i]=='a') sum+=1;
		else if(s[i]=='b') sum+=2;
		else if(s[i]=='c') sum+=3;
		else if(s[i]=='d') sum+=4;
		else if(s[i]=='e') sum+=5;
		else if(s[i]=='f') sum+=6;
		else if(s[i]=='g') sum+=7;
		else if(s[i]=='h') sum+=8;
		else if(s[i]=='i') sum+=9;
		else if(s[i]=='j') sum+=10;
		else if(s[i]=='k') sum+=11;
		else if(s[i]=='l') sum+=12;
		else if(s[i]=='m') sum+=13;
		else if(s[i]=='n') sum+=14;
		else if(s[i]=='o') sum+=15;
		else if(s[i]=='p') sum+=16;
		else if(s[i]=='q') sum+=17;
		else if(s[i]=='r') sum+=18;
		else if(s[i]=='s') sum+=19;
		else if(s[i]=='t') sum+=20;
		else if(s[i]=='u') sum+=21;
		else if(s[i]=='v') sum+=22;
		else if(s[i]=='w') sum+=23;
		else if(s[i]=='x') sum+=24;
		else if(s[i]=='y') sum+=25;
		else if(s[i]=='z') sum+=26;
		else if(s[i]<='Z'&&s[i]>='A') sum=sum+(int(s[i])-(int(s[i])*2));
	}
	cout<<sum;
	return 0;
}

B4003 [GESP202406 三级] 移位

题目传送门:[GESP202406 三级] 移位 - 洛谷

题目描述

小杨学习了加密技术移位,所有大写字母都向后按照⼀个固定数目进行偏移。偏移过程会将字母表视作首尾相接的环,例如,当偏移量是 3 的时候,大写字母 A 会替换成 D,大写字母 Z 会替换成 C,总体来看,大写字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ 会被替换成 DEFGHIJKLMNOPQRSTUVWXYZABC。

注:当偏移量是 26 的倍数时,每个大写字母经过偏移后会恰好回到原来的位置,即大写字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ 经过偏移后会保持不变。

输入格式

第一行包含一个正整数 n。

输出格式

输出在偏移量为 n 的情况下,大写字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ 移位替换后的结果。

输入输出样例

输入 #1复制

3

输出 #1复制

DEFGHIJKLMNOPQRSTUVWXYZABC

说明/提示

【样例解释】

当偏移量是 3 的时候,大写字母 A 会替换成 D,大写字母 Z 会替换成 C,总体来看,大写字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ 会被替换成 DEFGHIJKLMNOPQRSTUVWXYZABC。

【数据范围】

对于全部数据,保证有 1≤n≤100。

这道题也很简单(但是我考的时候没有想出正解),先判断偏移量是否是26的倍数,否则按照偏移量输出字符串。下面是AC代码:

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	string s="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	if(n%26==0){
		cout<<s;
		return 0;
	}
	for(int i=n%26;i<26;i++) cout<<s[i];
	for(int i=0;i<n%26;i++) cout<<s[i];
	return 0;
}

好了,今天的题解就到这里了,我们下期再见!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值