刚刚结束计算机能力挑战赛的区域赛,也就是省赛,我参加的是程序设计赛c++方向,回顾自己的参赛经历,总结了下比赛的相关题目如下:
20年真题
一、选择
1.阅读以下语句:double m=0;for(int i=3;i>0;i–)m+=1/i;将m保留三位小数输出,结果为(B)
A.0 B.1 C.1.833 D.6
2.下列选项中,不是C++关键字的是(C)
A. namespace B.typename C.main D.class
3.下列选项中,运算结果的数据类型为double的选项是(B)
A. ‘A’+‘B’-‘C’ B.2-3.0*0 C.(int)1.0+5 D.10LL-10
4.下列运算结果的数据类型是int的选项为(D)
A. 1 B.1LL C.‘A’ D.‘A’+1
5.关于C++数据类型,下列描述错误的是(C)
A. 相同数据类型所占字节数在不同系统中可能不同 B.枚举类型是C++中的一种派生数据类型 C.对于小数1.0,其默认数据类型是float D.数据类型转换有自动转换、赋值转换、强制转换
6.阅读以下代码:
int main()
{
int x=100;
cout<<__①__<<x<<__②__<<" "<<x;
return 0;
},
若程序输出结果为64 144,则下列选项中描述正确的是(C)
A. 可将①补全为oct,②补全为hex,输出结果为64 144 B.100的二进制为11000010 C.cout是一个ostream类的对象D.变量x与0x144相等
7.下列选项中与控制输出精度有关的函数为(C)
A. setf() B.width() C.setprecision() D.fill()
8.关于C++输入输出,下列描述错误的是(C)(io类每年都考,今年也是!)
A. getline()可以接收一个字符串,包括空格 B.ofstream类的对象可以输出到文件 C.cin.getline()和getline()是一样的函数 D.cerr和clog流对象都是标准错误流,但存在一些区别
9.若有int a;char b;string c;cin>>a>>b>>c;则下列输入形式错误的是(D)
A. 1<回车>a<回车>abc B.1 a abc C.1a abc D.1,a,abc
10.下列位运算表达式的结果为2的选项是(B)
A. ~(-2)&2+1 B.5^6+1 C.4%3*7/2 D.4>=5?1+2:2+3
11.对于32位机,已知int x=1;下列选项中错误的是(D)
A. x<<36的值与x<<4的相等 B.~(-(x+1000))的值等于1000 C.-1的二进制为32个1D.x<<31+1的值为负数
12.下列运算符中,不属于关系运算符的是(C)
A. != B.== C.<<= D.<=
13.设char型变量x中的值为1010 1010,则表达式(x+5)^(-1)的计算结果的二进制为(A)
A. 0101 0000 B.1010 1111C.1111 1111D.0101 0001
14.关于位运算,下列描述正确的是(C)
A. 位运算适用于所有基本数据类型 B.位运算的效率普遍较低C.~(-3)的值为2D.符号位不参与位运算
15.若有一个3x3的int型二维数组n,第一、二、三行分别存储数据为{1,2,3}、{4,5,6}、{7,8,9},有一个int型指针p,p=n[0];则(* (p+2)+2)的值为(D)
A.2 B.3C.4D.5
二、大题
1.Excel表列名称由字母A~Z组成,列字母的规律如下:
A、B、C…Z、AA、AB…AZ、BA、BB…ZZZZY、ZZZZZ…
输入:
输入包含两个列名称字符串,长度均小于等于5。
输出:
输出两个列名称之间共有多少列
样例输入:
AA AZ
样例输出:
24
2.九键拼音中数字与英文字母成对应关系:2–abc, 3-def, 4-ghi, 5–jkl, 6–mno, 7–pqrs, 8–tuv, 9–wxyz。
输入:
输入一个由英文小写字母组成的字符串(长度<=100000)
输出:
输出其对应的九键数字。
样例输入:
fwgeta
样例输出:
394382
3.给定两个字符串str1和str2(长度均<=10000),问字符串str2内每个字符是否能在字符串str1内找到
输入:
第一行输入字符串str1
第二行输入字符串str2
输出:
若能找到,则输出‘Y’,否则输出‘N’;
样例输入:
abdcdewrtde
wbaqx
样例输出:
YYYNN
4.有N个正整数,求这N个正整数两两之间的最大公约数之积
输入:
第一行输入正整数N(N<=100)
第二行有N个正整数(<10000)
输出:
输出这N个正整数两两之间的最大公约数之积,结果对1000000007取模
样例输入:
4
6 8 9 10
样例输出:
24
21年真题
一、选择
1.已有函数原型int f(int &x)。在执行语句int n=1;后下面下列选项执行函数调用正确的是( B)
A.int f(n); B.f(n); C.f(&n); D.f(1);
2.C++中带默认参数的函数原型正确的是(D)
A. int f(int x=10,int y,int z=30); B.int f(int x=10,int y=20,int z); C.int f(int x,int y=20,int z);D.int f(int x,int y=20,int z=30);
3.关于函数的说法,不正确的是( D )
A. 函数可以没有参数 B.函数可以没有返回值 C.函数可以嵌套调用 D.在一个函数中可以嵌套定义另一个函数
4.下列关键词中,是类成员访问控制说明符有(A)
A. protected B.extern C.inline D.class
5.对于一个类Base,语句Base b; 则执行此语句将调用类Base的(A)
A. 无参构造函数 B.拷贝构造函数 C.析构函数 D.静态成员函数
6.如果一个类没有定义构造函数,描述正确的是(D )
A. 程序编译时会提示错误 B.这个类没有析构函数 C.定义该类对象时就不会调用构造函数D.编译器会提供一个不带参数的构造函数
7.C++中this指针描述错误的是(C)
A. 非静态成员函数内部可以直接使用 this 关键字 B.this 代表指向该函数所作用的对象的指针C.使基类公有成员在子类中可以被访问 D.静态成员函数在其内部不能使用 this 指针
8.下列关于C++类的静态成员变量概念的描述,不正确的是(D)
A. 静态成员变量属于整个类所有,所有对象共享类的静态成员变量 B.静态成员变量的生命周期不依赖于任何对象 C.可以通过类名和对象名访问public静态成员变量 D.静态成员变量在类的内部定义与初始化
9.下列关于C++类的友元概念的描述,错误的是(D)
A. 类 A 将类 B 声明为自己的友元,则类 B 的所有成员函数就都可以访问类 A 对象的私有成员 B. 友元关系在类之间不能传递,即类 A 是类 B 的友元,类 B 是类 C 的友元,并不能导出类 A 是类 C 的友元 C. 在类中用friend关键词声明友元函数D. 友元函数是类的成员函数
10.类B是类A的派生类,当定义类B的一个对象和删除这个对象时,调用构造函数和析构函数的次序分别为(A)
A. A构造函数 B构造函数 B析构函数 A析构函数 B. A构造函数 B构造函数 A析构函数 B析构函数 C. B构造函数 A构造函数 B析构函数 A析构函数D. B构造函数 A构造函数 A析构函数 B析构函数
11.类B中有一个类A的对象成员,当定义类B的一个对象和删除这个对象时,调用构造函数和析构函数的次序分别为(A)
A. A构造函数 B构造函数 B析构函数 A析构函数 B. A构造函数 B构造函数 A析构函数 B析构函数 C. B构造函数 A构造函数 B析构函数 A析构函数D. B构造函数 A构造函数 A析构函数 B析构函数
12.一个类有多个对象成员,这些对象成员调用构造函数的顺序(C)
A. 与这些对象成员在成员初始化列表的顺序相同 B.与这些对象成员在成员初始化列表的顺序相反 C.与这些对象成员在类中说明的顺序相同D.与这些对象成员在类中说明的顺序相反
13.类A拷贝构造函数的原型是(A)
A. A(const A&); B.A();C.A& A(const A&);D.A& A();
14.下列哪种情况不调用拷贝构造函数(D)
A. 一个对象作为函数参数,以值传递的方式传入函数体B.一个对象作为函数返回值,以值传递的方式从函数返回;C.一个对象用于给另外一个对象进行初始化D.一个对象被定义为另一个对象的引用时
15.C++中使用 new所分配的存储空间,释放时要使用 ( A )
A.delete B.freeC.mallocD.destructor
二、大题
1.表达式求值
老式的计算机只能按照固定次序进行运算,华安大学就有这样一台老式计算机,计算模式为A @ B #C,@和#为输入的运算符(可能是+、*、%,须考虑计算优先级),现给出A,B,C的数值以及@和#对应的运算符,请你编写程序,验证老式计算机的运行结果。
输入说明:
第一行是一个整数N(|N|≤10000),表示有N组计算数据需要处理,接下来N行,每行是相应的数据,包括三个整数和两个运算符,分别对应A、@、B、#和C。
输出说明:
对每行输入的数据,输出计算结果。
输入样例:
3
1+2*3
3%2+1
5+7%9
输出样例:
7
2
12
按照最后一次提交的代码为评分标准。
2.信息整理
某机房上线了一套系统,和每台计算机都相连,以便监控各计算机相关外设的运行状态。各计算机的返回信号映射为一个0-15的数,其中从左到右第0位为1表示键盘故障、第1位为1表示鼠标故障、第2位为1表示显示故障、第3位为1表示声音故障。
如7对应0111,表示鼠标、显示、声音同时故障。
先输入这N台计算机的状态,请统计显示故障但声音正常的计算机数量。
输入说明:
第一行是一个N(0<N≤1000),表示计算机的数量。接下来N行,每行是一个0-15的数字。
输出说明:
一个整数,表示机房里显示故障但声音正常的计算机数量。
输入样例:
5
12
3
1
2
4
输出样例:
1
按照最后一次提交的代码为评分标准。
3.子串替换
给定一个字符串S,和一个特定子串S1,如果该子串第k次出现则进行替换(ababa 视为出现了2次子串aba),替换规则是将子串中的每个英文字母修改为循环后移1位的字母(即a换成b,b换成c,依次类推,z换成a,大写字母同样处理),其他字符不变。现在请你编写程序,输出替换后的字符串;如果不发生替换,输出F。
输入说明:
第一行输入整数k(0<k≤256)、子串S1(S1不包含空格,长度不超过256),中间以空格间隔。
第二行是需要处理的字符串S(长度不超过256)。
输出说明:
输出替换后的字符串;如果不发生替换,输出F。
输入样例:
2 re
There is a small tree in the garden.
输出样例:
There is a small tsfe in the garden.
按照最后一次提交的代码为评分标准。
4.智能除草
农业植保无人机作为最新的设备,可以加注除草剂进行除草。每次工作可以喷洒边长为K的正方形区域。现有一块边长为N的正方形农田,将其分成N*N个方格单元,已知每个单元里的杂草数量。求该植保无人机一次工作最多可以除草的数量。
输入说明:
第一行是2个正整数,分别为N和K(1≤K≤N≤1000)。
之后N行N列正整数,表示每个单元中的杂草数量(不超过50)。
输出说明:
该植保无人机一次工作最多可以除草的数量。
输入样例:
5 2
2 2 1 1 1
1 2 1 5 6
6 1 1 4 5
2 6 1 1 1
1 1 1 1 1
输出样例:
20
按照最后一次提交的代码为评分标准。
补充(官方大题练习网站 link )
由于上面的网站算法题题解不多,这里再附上自己的一些题的题解,题目名称与官网对应,非大佬,有些地方写的不是最优解答,希望大家在评论区多多指教
1.回文时钟(省赛也考了一道时钟计算时间的)
小爱同学最近特别迷恋回文字符串。以至于他看时间都想找到回文字符串,现在题目中会给你一个时间字符串 s(形式如 HH:MM 24 小时制)请你找到这一个时刻之前的一个回文时间和之后的一个回文时间并输出。
如 s=01:00,之前的一个回文时间为 00:00,之后的一个回文时间为 01:10。但输出输出不含前导 0。故输出 0:0,1:10。
现在请你编写代码,完成上述操作。
输入输出格式
输入格式
一个字符串 s。
输出格式
第一行,一个字符串代表之前的一个回文时间。
第二行,一个字符串代表之后的一个回文时间。
#include<bits/stdc++.h>
using namespace std;
/* 判断是否为回文,通过模运算判断每一位对应数字,太妙了!!! */
bool isHW(int h,int m){
if(h/10==m%10&&h%10==m/10){
return true;
}
return false;
}
int main(){
char a[5];
while(cin>>a){
/* 先分别计算出小时和分钟数 */
int x=(a[0]-'0')*10+(a[1]-'0');
int y=(a[3]-'0')*10+(a[4]-'0');
int m_sum=x*60+y;
/* 先算之前的回文时间,往前遍历 */
for(int i=m_sum-1;i>=0;--i){
int h=i/60;
int m=i%60;
if(isHW(h,m)){
cout<<h<<":"<<m<<endl;
break;
}
}
/* 然后算之后的回文时间,往后遍历 */
for(int i=m_sum+1;i<1440;++i){
int h=i/60;
int m=i%60;
if(isHW(h,m)){
cout<<h<<":"<<m<<endl;
break;
}
}
}
}
2.孔融让梨
孔融让梨一直是中国古代故事中谦逊的榜样。今天孔融又拿到了一些梨,他决定分给他的兄弟们,由于孔融很谦逊,他必须保证分给他兄弟的梨比自己的梨多。题目中会给你一行两个整数 n 和 k 代表,孔融要分给 n 个兄弟和他手里有 k 个梨。现在请你编写代码帮孔融计算,他最多能吃到多少个梨。
输入输出格式
输入格式
一行两个整数 n 和 k。
输出格式
一个整数。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,k;
while(cin>>n>>k){
/* 以大家一起分的平均数取整为上限(因为孔融是要最少的,故他肯定比平均少,由于这里是取整故可以以它作为孔融得到梨的上限) */
for(int i=k/(n+1);i>=0;--i){
/* 这里减去孔融得到的梨和其余兄弟们的平均数作对比,判断是否有比孔融少的 */
if((k-i)/n>i){
cout<<i;
break;
}
}
}
}
3.小熊吃水果
小熊采摘回来了三种水果,他决定每天吃两个不同种类的水果各一个。在题目中会给你三个整数 a,b,c,分别代表三种水果的数量,现在请你编写代码,帮小熊算一下他最多能吃多少天?
输入输出格式
输入格式
一行三个整数 a,b,c。
输出格式
一个整数。
#include<bits/stdc++.h>
using namespace std;
int main(){
/* 永远只吃剩下数量最多的两个品种,模拟这个过程即可 */
int fruit[3];
for(int i=0;i<3;++i){
cin>>fruit[i];
}
sort(fruit,fruit+3);
int ans=0;
while(fruit[1]&&fruit[2]){
ans++;
fruit[1]--;
fruit[2]--;
sort(fruit,fruit+3);
}
cout<<ans;
}
4.丑数Ⅱ(力扣有同名题目,这里就不解析了,动规其实考的很少)
给你一个整数 n ,请你找出并返回第 n 个丑数。
丑数就是只包含质因数 2、3 或 5 的正整数。
输入输出格式
输入格式
一个整数 n。
输出格式
一个整数。
#include <iostream>
#include <vector>
using namespace std;
int nthUglyNumber(int n) {
vector<int> dp(n);
dp[0] = 1;
int i2 = 0, i3 = 0, i5 = 0;
for (int i = 1; i < n; i++) {
int next2 = dp[i2] * 2, next3 = dp[i3] * 3, next5 = dp[i5] * 5;
dp[i] = min(next2, min(next3, next5));
if (dp[i] == next2) i2++;
if (dp[i] == next3) i3++;
if (dp[i] == next5) i5++;
}
return dp[n - 1];
}
int main() {
int n;
while(cin>>n){
cout <<nthUglyNumber(n) << endl;
}
return 0;
}
5.消灭兔子
小明正在陪朋友逛街,遇到了一个消灭免子的游戏。
游戏规则很简单,用箭杀死免子即可。
箭是一种消耗品,已知有多种类型的箭可以选择,并且每种箭都会对兔子造成伤害,每种箭需要一定的现金购买。
假设每种箭只能使用一次,每只免子也只能被射一次,请计算要消灭地图上的所有兔子最少需要的现金数量。
输入输出格式
输入格式
第一行有两个整数 n,m,分别表示兔子的个数和箭的种类;
第二行有 n 个正整数,分别表示兔子的血量;
第三行有 m 个正整数,表示每把箭所能造成的伤害值;
第四行有 m 个正整数,表示每把箭需要花费的现金数。
当箭的伤害值大于等于兔子的血量时,就能将兔子杀死。
整数之间以空格间隔。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
while(cin>>n>>m){
/* 接受输入放到三个vector里 */
vector<int> rabbit(n);
vector<int> arrow(m);
vector<int> gold(m);
/* 以现金为key,箭的伤害为value,利用map进行排序 */
multimap<int,int> gold_arr;
for(int i=0;i<n;++i){
cin>>rabbit[i];
}
for(int j=0;j<m;++j){
cin>>arrow[j];
}
for(int k=0;k<m;++k){
cin>>gold[k];
}
if(n>m){
cout<<"No";
break;
}
for(int k=0;k<m;++k){
gold_arr.insert(make_pair(gold[k],arrow[k]));
}
sort(rabbit.begin(),rabbit.end());
int sum=0;
bool isFind;
/* 将兔子血量从大到小遍历,优先用又便宜伤害又高的箭消灭血量最高的兔子 */
for(int i=n-1;i>=0;--i){
isFind=false;
multimap<int,int>::iterator it;
/* 每次遍历有没有对应的箭来消灭兔子,有就isFind设为true */
for(it=gold_arr.begin();it!=gold_arr.end();it++){
if(it->second>=rabbit[i]){
isFind=true;
sum+=it->first;
break;
}
}
gold_arr.erase(it);
if(!isFind){
cout<<"No";
break;
}
}
if(isFind){
cout<<sum;
}
}
}
6.最长上升子序列(力扣原题)
给定一个数组 nums,请编写程序将数组 nums 中严格递增子序列(如1,2,5,8)寻找出来;
输入输出格式
输入格式
输入一共为两行,第一行为即将输入数组的数字数量;
第一行为一个数字n,表示数组包含n 个数字,第二行包括为数组所有数,数字之间通过通过空格分开。
输出格式
输出程序计算得到的最长上升子序列的数字个数。
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n;
while(cin >> n){
vector<int> height(n, 0);
for(int i = 0; i < n; i ++){
cin >> height[i];
}
vector<int> f(n, 1);
int result = 1;
for(int i = 1; i < n; i ++){
for(int j = 0; j < i; j ++){
if(height[i] > height[j]){
f[i] = max(f[i], f[j] + 1);
}
}
result = max(result, f[i]);
}
cout << result << endl;
}
}
7.猴子吃桃问题(找规律即可)
猴子第一天摘下若干个桃子,当天吃了一半,后面又多吃一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。后面每天猴子都吃了前一天剩下的一半零一个。到第十天想再吃时,只剩下一个桃子。求第一天共摘了多少桃子。
输入格式
无。
输出格式
一个整数。
#include<bits/stdc++.h>
using namespace std;
int main(){
int ans=1;
for(int i=0;i<9;++i){
ans=(ans+1)*2;
}
cout<<ans;
}
8.冒泡排序法的次数(感觉原题的意思就是找冒泡最少执行轮次,优化一下冒泡排序即可)
现在题目中会给你一个整数数组 num,小明会用冒泡排序法对其进行排序,现在请你编写代码,求最少的选择次数,使数组 num 变为升序。
输入输出格式
输入格式
第一行,一个整数 n 代表 num 的长度。
第二行,一行整数代表 num。
输出格式
一个整数。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
while(cin>>n){
vector<int> nums(n);
for(int i=0;i<n;++i){
cin>>nums[i];
}
int count=0;
for(int i=0;i<n-1;++i){
bool isSwap=false;
for(int j=0;j<n-i-1;++j){
if(nums[j]>nums[j+1]){
isSwap=true;
int temp=nums[j];
nums[j]=nums[j+1];
nums[j+1]=temp;
}
}
/* 加个标志位,没发生交换就提前退出 */
if(!isSwap){
break;
}
/* 记录轮数 */
count++;
}
cout<<count;
}
}
9.最小之和
题目中会给你一个正整数 a 和 b(初始 a=b)。然后你可以先用 a 减去小于等于 b 的任意一个数(该数必须大于等于零)。接下来你可以拿处理后的 b 减去小于等于 a 的数。最后再重新处理一次 a,如此执行三次以后,请你编写代码计算 a 和 b 数字之和的最小值。(注意 a 和 b 做差时不能减为负数)
输入输出格式
输入格式
一行两个整数 a 和 b。
输出格式
一个整数。
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b;
while(cin>>a>>b){
a-=b/2;
b-=a;
a-=b;
int ans=a+b;
cout<<ans;
}
}
10.吃苹果(也是找规律)
小熊有很多苹果,每一天小熊会数出自己的苹果个数 n。如果 n 是偶数,小熊就会吃掉 n/2个苹果,如果 n 是奇数,小熊就会吃掉 (n+1)/2 个苹果。现在小熊吃了 k 天,还剩下最后一个苹果,现在小熊想知道 k 天前一共有多少苹果。当然,可能性不止一种,所以请你编写代码帮小熊计算出 k 天前他的苹果数量有多少种可能?
输入输出格式
输入格式
一个整数 k。
输出格式
一个整数。
#include <iostream>
#include <cmath>>
using namespace std;
int main(){
int k;
while(cin>>k){
cout<<pow(2,k);
}
}
赛后总结
1.c++ acm模式做题万能头文件 #include<bits/stdc++.h>
2.题目选择15道,大题(算法题4道),省赛四道都是中等题,说是中等但其中两道感觉挺简单的
3.省赛大题大概率考察字符串、数组、基础数据结构,dp,回溯感觉考的较少,但国赛可能会出
省流:蓝桥杯mini版,适合c++刚学完基础,算法刷了100来道的uu们,刷创新分的也推荐冲,难度一般,比较好水,比赛排名也较高