第七届蓝桥杯(软件类)省赛C++C组真题题解
题目链接
C组真题
注:其余题目同A组,B组真题,这里不作重复,传送门:A组真题题解传送门 B组真题题解传送门
题目结构
| 题目 | 类型 | 分值 |
|---|---|---|
| 第一题 | 结果填空 | 3分 |
| 第二题 | 结果填空 | 5分 |
| 第三题 | 结果填空 | 7分 |
| 第四题 | 代码填空 | 11分 |
| 第五题 | 代码填空 | 13分 |
| 第六题 | 结果填空 | 15分 |
| 第七题 | 结果填空 | 19分 |
| 第八题 | 程序设计 | 21分 |
| 第九题 | 程序设计 | 25分 |
| 第十题 | 程序设计 | 31分 |
第一题 报纸页数
-
问题重现
X 星球日报和我们地球的城市早报是一样的,
都是一些单独的纸张叠在一起而已。每张纸印有 4 版。比如,某张报纸包含的 4 页是: 5,6,11,12 ,
可以确定它应该是最上边的第 2 张报纸。我们在太空中捡到了一张 X 星球的报纸, 4 个页码分别是:
1125,1126,1727,1728请你计算这份报纸一共多少页(也就是最大页码 , 并不是用了几张纸哦)?
请填写表示总页数的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。 -
解题思路
这道题其实特别简单,我们来先解释一下报纸的页码排版,假设有 n n n页的报纸,那么第一张就是 1 , 2 , n − 1 , n 1,2,n-1,n 1,2,n−1,n,以此类推。这实际上就是以报纸中间对称的,而且,对于捡到的一张报纸页码 a , b , c , d a,b,c,d a,b,c,d,其中 a a a就是代表了从第一页到第 a a a页的页数,由于是对称的,所以 d d d到最后一页的页数等于 a a a。那么还剩 b , c b,c b,c 之间的页数,这也特别简单,根据页码差,直接是 c − b + 1 c-b+1 c−b+1。故此题可得为 a × 2 + c − b + 1 a\times 2+c-b+1 a×2+c−b+1。
-
代码
/**
*@filename:报纸页数
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-20 21:17
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;
int a,b,c,d;
void solve(){
cout<<a*2+c-b+1<<endl;
}
int main() {
a=1125,b=1126,c=1727,d=1728;
solve();
return 0;
}
-
答案
2852 2852 2852。
第三题 平方怪圈
-
问题重现
如果把一个正整数的每一位都平方后再求和,得到一个新的正整数。
对新产生的正整数再做同样的处理。如此一来,你会发现,不管开始取的是什么数字,
最终如果不是落入 1 ,就是落入同一个循环圈。请写出这个循环圈中最大的那个数字。
请填写该最大数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。 -
解题思路
根据题意去做即可。
-
代码
/**
*@filename:平方怪圈
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-20 21:35
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;
//我们先进行测试,看出现什么样的循环。
int n=5;
void change(int &n){
int result=0;
//得到循环圈最大是145.
while(n>0){
result+=pow(n%10,2);
n/=10;
}
n=result;
}
void solve(){
int maxx=0;
for(int i=0;i<100;i++){
change(n);
maxx=max(maxx,n);
}
cout<<maxx<<endl;
}
int main() {
solve();
return 0;
}
-
答案
145 145 145。
第四题 打印方格
-
问题重现
小明想在控制台上输出 m x n 个方格。
比如 10x4的,输出的样子是:
±–±--±–±--±–±--±–±--±–±--+
| | | | | | | | | | |
±–±--±–±--±–±--±–±--±–±--+
| | | | | | | | | | |
±–±--±–±--±–±--±–±--±–±--+
| | | | | | | | | | |
±–±--±–±--±–±--±–±--±–±--+
| | | | | | | | | | |
±–±--±–±--±–±--±–±--±–±--+以下是小明写的程序,请你分析其流程,填写划线部分缺少的代码。
#include <stdio.h> //打印m列,n行的方格 void f(int m, int n) { int row; int col; for(row=0; row<n; row++){ for(col=0; col<m; col++) printf("+---"); printf("+\n"); for(col=0; col<m; col++) printf("| "); printf("|\n"); } printf("+"); _____________________________; //填空 printf("\n"); } int main() { f(10,4); return 0; }注意:仅仅填写划线部分缺少的内容,不要添加任何已有内容或说明性文字。
-
解题思路
观察可知,我们还有最后一行没有打印,而对于这 m m m个空格,其中一个空格对应着"—+",故我们打印 m m m个即可。
-
答案
for(col =0;col<m;col++)printf("---+")
第八题 冰雹数
-
问题重现、
任意给定一个正整数N,
如果是偶数,执行: N / 2
如果是奇数,执行: N * 3 + 1生成的新的数字再执行同样的动作,循环往复。
通过观察发现,这个数字会一会儿上升到很高,
一会儿又降落下来。
就这样起起落落的,但最终必会落到“1”
这有点像小冰雹粒子在冰雹云中翻滚增长的样子。比如N=9
9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9的时候,这个“小冰雹”最高冲到了52这个高度。输入格式:
一个正整数N(N<1000000)
输出格式:
一个正整数,表示不大于N的数字,经过冰雹数变换过程中,最高冲到了多少。例如,输入:
10
程序应该输出:
52再例如,输入:
100
程序应该输出:
9232 -
解题思路
直接遍历不大于 n n n的所有数进行操作求出最大值即可。注意用 l o n g l o n g long\space\space long long long存储。
-
代码
/**
*@filename:冰雹数
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-20 21:49
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;
ll n;
void solve(){
ll maxx=n;
for(ll i=2;i<=n;i++){
ll temp=i;
while(temp!=1){
while(temp%2==0){
temp/=2;
}
if(temp==1){
break;
}
temp=temp*3+1;
maxx=max(maxx,temp);
}
}
cout<<maxx<<endl;
}
int main() {
while(cin>>n){
solve();
}
return 0;
}
第九题 卡片交换
-
问题重现
你玩过华容道的游戏吗?
这是个类似的,但更简单的游戏。
看下面 3 x 2 的格子±–±--±–+
| A | * | * |
±–±--±–+
| B | | * |
±–±--±–+在其中放5张牌,其中A代表关羽,B代表张飞,*代表士兵。
还有一个格子是空着的。你可以把一张牌移动到相邻的空格中去(对角不算相邻)。
游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。输入格式:
输入两行6个字符表示当前的局面输出格式:
一个整数,表示最少多少步,才能把AB换位(其它牌位置随意)例如,输入:
* A
**B程序应该输出:
17再例如,输入:
A B***
程序应该输出:
12资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms请严格按要求输出,不要画蛇添足地打印类似:“请您输入…”的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
-
解题思路
这道题有点趣味,我们要把空格当成一个可动的点,同时我们需要将地图一维化,因为这样方便我们地图去重,那么地图上的点就通过坐标映射来得到。这样,我们就可以进行 b f s bfs bfs了,首先定义一个结构体来存储空格点的状态,结构如下:
struct node{ int x,y,step;//(x,y)表示坐标,step代表所移动步骤。 string str;//代表当前地图。 };那么我们需要一个 g o go go数组来定义方向,以及 q u e u e queue queue队列来进行 b f s bfs bfs。值得注意的一点就是进行地图的转移,直接利用字符交换即可实现目的。具体看代码。
-
代码
/**
*@filename:卡片换位
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-21 10:38
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;
struct node{
int x,y,step;//(x,y)表示坐标,step代表所移动步骤。
string str;//代表当前地图。
};
int go[][2]={1,0,-1,0,0,1,0,-1};
map<string,int> p;
int sx,sy,ax,ay,bx,by;
string graph;
void bfs(){
p.clear();
queue<node> q;
node head,temp;
head.x=sx,head.y=sy,head.step=0,head.str=graph;
p[head.str]++;
q.push(head);
while(!q.empty()){
head=q.front();
q.pop();
if(head.str[ax*3+ay]=='B'&&head.str[bx*3+by]=='A'){
cout<<head.step<<endl;
return;
}
for(int i=0;i<4;i++){
temp.x=head.x+go[i][0],temp.y=head.y+go[i][1];
if(temp.x<0||temp.x>=2||temp.y<0||temp.y>=3)continue;
temp.str=head.str,temp.step=head.step+1;
swap(temp.str[temp.x*3+temp.y],temp.str[head.x*3+head.y]);
if(p[temp.str])continue;
p[temp.str]++;
q.push(temp);
}
}
}
void solve(){
for(int i=0;i<6;i++){
if(graph[i]==' '){
sx=i/3;
sy=i%3;
}
else if(graph[i]=='A'){
ax=i/3;
ay=i%3;
}
else if(graph[i]=='B'){
bx=i/3;
by=i%3;
}
}
bfs();
}
int main() {
string str1,str2;
while(getline(cin,str1)){
getline(cin,str2);
graph=str1+str2;
solve();
}
return 0;
}

浙公网安备 33010602011771号