第七届蓝桥杯(软件类)省赛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,n1,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 bc 之间的页数,这也特别简单,根据页码差,直接是 c − b + 1 c-b+1 cb+1。故此题可得为 a × 2 + c − b + 1 a\times 2+c-b+1 a×2+cb+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;
}
posted @ 2022-03-26 16:49  unique_pursuit  阅读(80)  评论(0)    收藏  举报