GESPC++三级编程题 知识点


4141:【GESP2509三级】数组清零

【题目描述】

⼩ A 有⼀个由n 个⾮负整数构成的数组 a=[a1,a2,...,an]。他会对数组a 重复进⾏以下操作,直到数组a 只包含0。在⼀次操作中,⼩ A 会依次完成以下三个步骤:

  1. 在数组 a 中找到最⼤的整数,记其下标为k 。如果有多个最⼤值,那么选择其中下标最⼤的。

  2. 从数组a 所有不为零的整数中找到最⼩的整数aj 。

  3. 将第⼀步找出的ak 减去aj 。

例如,数组a=[2,3,4] 需要7 次操作变成[0,0,0] :

2,3,4\]→\[2,3,2\]→\[2,1,2\]→\[2,1,1\]→\[1,1,1\]→\[1,1,0\]→\[1,0,0\]→\[0,0,0

⼩ A 想知道,对于给定的数组a ,需要多少次操作才能使得a 中的整数全部变成0 。可以证明,a 中整数必然可以在有限次操作后全部变成0 。你能帮他计算出答案吗?

【输入】

第⼀⾏,⼀个正整数n ,表⽰数组a 的长度。

第⼆⾏, n个⾮负整数a1,a2,...,an ,表⽰数组a 中的整数。

【输出】

⼀⾏,⼀个正整数,表示a 中整数全部变成0 所需要的操作次数。

【输入样例】

复制代码
3
2 3 4

【输出样例】

复制代码
7

【提示】

输入样例 2:

复制代码
5
1 3 2 2 5

输出样例 2:

复制代码
13

数据范围

对于所有测试点,保证1≤n≤100 ,1≤ai≤100。

【知识点】

1、三级及以上运行时容易超时,能提高运行效率的地方尽量去提高。
如本题运行的后半段会出现大量0,额外去满足 arr[i]!=0 可提高运行效率。
if(arr[i]!=0 && arr[i]<min0) min0=arr[i];

2、只知道循环结束条件,不知循环次数,最好用while循环。有时得用while(true)死循环。
如本题循环的条件是:数组没有全为0。
while后( )中的条件不好表示,
因此写while(true),循环中再进行循环终止的判断。

【答案】

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n, arr[105];
int main() {
	cin>>n;
	for(int i=0; i<n; i++) cin>>arr[i];
	int num=0; //记录操作次数 
	while(true){
		int maxid=0, min0=100; //maxid:满足条件的最大值下标, min0:最小值 
		for(int i=0; i<n; i++){ 
			if(arr[i]>=arr[maxid]) maxid=i;
			//运行的后半段会出现大量0,额外满足arr[i]!=0可提高运行效率。 
			if(arr[i]!=0 && arr[i]<min0) min0=arr[i];
		}
		if(arr[maxid]==0) break; //最大值为0,即数组中已全为0 
		arr[maxid]-=min0; //按题目要求进行操作 
		num++; //操作次数加1 
	}
	cout<<num;
	return 0;
}

4142:【GESP2509三级】⽇历制作

【题目描述】

⼩ A 想制作 2025 年每个⽉的⽇历。他希望你能编写⼀个程序,按照格式输出给定⽉份的⽇历。

具体来说,第⼀⾏需要输出 MON TUE WED THU FRI SAT SUN,分别表⽰星期⼀到星期⽇。接下来若⼲⾏中依次输出这个⽉所包含的⽇期,⽇期的个位需要和对应星期⼏的缩写最后⼀个字母对齐。例如,2025 年 9 ⽉ 1 ⽇是星期⼀,在输出九⽉的⽇历时,1 号的个位 1 就需要与星期⼀ MON 的最后⼀个字母 N 对齐。九⽉的⽇历输出效果如下:

复制代码
MON TUE WED THU FRI SAT SUN
  1   2   3   4   5   6   7
  8   9  10  11  12  13  14
 15  16  17  18  19  20  21
 22  23  24  25  26  27  28
 29  30

你能帮助⼩ A 完成⽇历的制作吗?

【输入】

⼀⾏,⼀个正整数m ,表⽰需要按照格式输出 2025 年m ⽉的⽇历。

【输出】

输出包含若⼲⾏,表⽰ 2025 年m ⽉的⽇历。

【输入样例】

复制代码
9

【输出样例】

复制代码
MON TUE WED THU FRI SAT SUN
  1   2   3   4   5   6   7
  8   9  10  11  12  13  14
 15  16  17  18  19  20  21
 22  23  24  25  26  27  28
 29  30

【提示】

输入样例 2:

复制代码
6

输出样例 2:

复制代码
MON TUE WED THU FRI SAT SUN
                          1
  2   3   4   5   6   7   8
  9  10  11  12  13  14  15
 16  17  18  19  20  21  22
 23  24  25  26  27  28  29
 30

数据范围:

对于所有测试点,保证1≤m≤12。

【知识点】

1、数组定义的同时,进行赋值时,不能填几个位置又空几个位置。要么都不填要么填满。
如本题:过程中要使用循环变量i来描述月份,月份的取值范围是1~12,没有0。
定义数组时最佳为:months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
其中数组的第一个位置不能为空。

2、当取值范围没有负数,但运算中有负数时,要规避负数。
如本题:题目已知25年9月第一天是星期一,通过常识也知道25年的每个月有多少天。
关键点是:要依据25年9月第一天是星期一来推出每个月的第一天是星期几。
可设变量start,来表示每个月的第一天的星期数,9月是初始为 1。
int start=1;
if(n<9){ //9月之前,往前计算天数
for(int i=8; i>=n; i--){
start-=months[i];
}
}else if(n>9){ //9月之后,往后计算天数
for(int i=9; i<n; i++){
start+=months[i];
}
}
//计算某月第一天是星期几,往前计算时会出现负数
start=(start%7+7)%7; //start%7的结果可能是负数,通过加7再对7做取余运算规避
if(start==0) start=7; //余数0是星期7

【答案】

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n, months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //25年是平年,2月28天。
int main() {
	cin>>n;
	cout<<"MON"<<" "<<"TUE"<<" "<<"WED"<<" "<<"THU"<<" "<<"FRI"<<" "<<"SAT"<<" "<<"SUN"<<endl;
	int start=1; //start某月第一天的星期数,已知信息:2025年9月1日是星期一。 
	if(n<9){ //9月之前,往前计算天数 
		for(int i=8; i>=n; i--){
			start-=months[i];
		}
	}else if(n>9){ //9月之后,往后计算天数 
		for(int i=9; i<n; i++){
			start+=months[i];
		}
	}
	//计算某月第一天是星期几,往前计算时会出现负数,start%7的结果可能是负数,通过加7再对7做取余运算规避 
	start=(start%7+7)%7;   
	if(start==0) start=7; //余数0是星期7 
	for(int i=1; i<start; i++){ //输出每月1号之前的空格
		cout<<setw(3)<<' '<<" "; //占3个字符右对齐输出
	} 
	//从1号到月底进行输出 
	for(int i=1; i<=months[n]; i++){
		cout<<setw(3)<<i<<" "; //占3个字符右对齐输出 
		if(start%7==0) cout<<endl; //每7天换行 
		start++;
	}  
	return 0;
}

4046:【GESP2403三级】完全平方数

【题目描述】

小杨同学有一个包含n 个非负整数的序列A ,他想要知道其中有多少对下标组合<i,j> (1≤i,j≤n,i<j ),使得Ai+Aj是完全平方数。

如果x 是完全平方数,则存在非负整数y 使得 y×y=x。

【输入】

第一行一个非负整数n ,表示非负整数个数。

第二行包含n 个非负整数A1,A2,...,An ,表示序列A 包含的非负整数。

【输出】

输出一个非负整数,表示和是完全平方数的非负整数对数。

【输入样例】

复制代码
5
1 4 3 3 5

【输出样例】

复制代码
3

【提示】

对于全部数据,保证有1≤n≤1000,0≤Ai≤105 。

【知识点】

1、注意题目已知变量的取值范围
如本题:i<j

2、判断一个数m是否是完全平方数:是否存在两个相同的整数相乘等于这个数

int t=int( sqrt(m) ); //计算m的平方根,强转成整数
if(t*t==m) num++; //一个整数的平方根强转为整数后,的平方如果等于自身

【答案】

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n, a[1005]={}, num=0;
int main(){
   cin>>n;
   for(int i=1; i<=n; i++) cin>>a[i];
   for(int i=1; i<=n; i++){
	  for(int j=i+1; j<=n; j++){ //保证i<j
		int m=a[i]+a[j]; //计算a[i]+a[j] 
		//判断m是否是完全平方数:存在两个相同的整数相乘等于这个数
		int t=int( sqrt(m) ); //计算m的平方根,强转成整数
		if(t*t==m) num++;  
   	  }
   }
   cout<<num;
   return 0;
}

4077:【GESP2409三级】平衡序列

【题目描述】

小杨有一个包含n个正整数的序列 a,他认为一个序列是平衡的当且仅当存在一个正整数i (1≤i<n )使得序列第1个到第i 个数字的总和等于第i+1 个到第n 个数字的总和。

小杨想请你判断序列a 是否是平衡的。

【输入】

第一行包含一个正整数t ,代表测试用例组数。

接下来是t 组测试用例。对于每组测试用例,一共两行。

第一行包含一个正整数n ,代表序列长度。

第二行包含n 个正整数,代表序列a 。

【输出】

对于每组测试用例,如果序列a 是否是平衡的,输出 Yes,否则输出 No

【输入样例】

复制代码
3
3
1 2 3
4
2 3 1 4
5
1 2 3 4 5

【输出样例】

复制代码
Yes
Yes
No

【提示】

对于第一组测试用例,令i=2 ,则有1+2=3 ,因此序列是平衡的;

对于第二组测试用例,令i=2 ,则有2+3=1+4 ,因此序列是平衡的;

对于第三组测试用例,不存在满足要求的i 。

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

【知识点】

1、当题目输出"YES"或"NO"时,可用假设法。切记,要注意输出的大小写。
如本题:第1个数~第n个数中,是否存在第i个数,使得编号1~i的和等于i+1~n的和。
可先假设这组数符合要求:bool flag=true;
当编号1~i的和的2倍 大于 编号1~n的和时,不符合要求:flag=false; 结束循环。
当编号1~i的和的2倍 等于 编号1~n的和时,符合要求:flag=true; 结束循环。
然后继续循环继续累加,如果没有符合条件的,一定会触发"编号1~i的和的2倍 大于 编号1~n的和"。

2、当题目有多组数据待判断要输出多个"YES"或"NO"时,
得把每组是否符合要求,重置为true或false,
经过代码循环测试完确定是否符合后。再判断输出结果:
bool flag=true;
......
if(flag) cout<<"YES"<<endl; //切记,要注意输出的大小写。
else cout<<"YES"<<endl;

【答案】

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int t, n, arr[10005];
int main() {
	cin>>t;
	while(t--){
		cin>>n;
		int sum=0; //sum存储所有元素的和 
		for(int i=1; i<=n; i++){
			cin>>arr[i];
			sum+=arr[i]; 
		} 
		int sumi=0; //sumi存储第1个到第i个数字的总和
		bool flag=true; //flag表示是否平衡,true为平衡。 
		for(int i=1; i<=n; i++){
			sumi += arr[i];
			if(sumi*2 > sum){ //sumi的2倍超过总和,不可能找到解,结束循环 
				flag=false; //不平衡时把true改成false。 
				break; 
			}else if(sumi*2 == sum){
				//平衡时依然是true,不用变。
				break; //结束循环
			}   
			//否则继续尝试 
		}
		if(flag) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}
相关推荐
milan-xiao-tiejiang2 小时前
ROS2面试准备
c++·面试·自动驾驶
koping_wu2 小时前
【leetcode】排序数组:快速排序、堆排序、归并排序
java·算法·leetcode
小O的算法实验室2 小时前
2025年AEI SCI1区TOP,基于自适应进化算法的城市空中交通多目标枢纽选址,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
week_泽2 小时前
题目 3330: 蓝桥杯2025年第十六届省赛真题-01 串
c++·贪心算法·蓝桥杯
历程里程碑2 小时前
LeetCode 283:原地移动零的优雅解法
java·c语言·开发语言·数据结构·c++·算法·leetcode
星火飞码iFlyCode2 小时前
iFlyCode实践规范驱动开发(SDD):招考平台报名相片质量抽检功能开发实战
java·前端·python·算法·ai编程·科大讯飞
leaves falling2 小时前
c语言-根据输入的年份和月份,计算并输出该月份的天数
c语言·开发语言·算法
jghhh012 小时前
锥束CT(CBCT)三维重构算法:FDK算法详解与实现
线性代数·算法·重构