蓝桥杯练习赛5--全解析

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯练习赛5--全解析相关的知识,希望对你有一定的参考价值。

JAM计数法

在这里插入图片描述

解题思路

在这里插入图片描述

解题代码

#include<bits/stdc++.h>
using namespace std;
//a数组用于存储str各个下标位置的编号(如'a'编号为1)
//limit数组用于存储各个位的限制
int a[26];
int limit[26];
int main()
{
    int s,t,w;
    string str;
    cin >> s >> t>>w>>str;  
    //更新各个位的序号
    for(int i=0;i<w;i++)a[i] = str[i]-'a'+1;
    //更新各个位的限制
    for(int i=0;i<w;i++)limit[i] = t-(w-i-1);
    //得到五个答案(每次循环得到一个答案,若没有5个则会根据情况跳出)
    for(int i=0;i<5;i++){
        if(a[0]==limit[0]) break;//如果首位等于限制位,则说明给出的字符是最后一个字符串,后面不可能存在了其他字符串
        for(int i=w-1;i>=0;i--){//从后往前判断
            if(a[i]==limit[i])//进位,该位此时不变,continue继续往前判断
            continue;
            //无进位,故停下,本位+1,并且让后面的所有位连续递增
            a[i]++;
            for(int j=i+1;j<w;j++){
                a[j] = a[j-1]+1;
            }//用printf输出字符后break即可
            for(int j=0;j<w;j++){
                printf("%c",a[j]+'a'-1);
            }cout<<endl;
            break;
    }   
}
}

动态数组使用

在这里插入图片描述

这题就不详解了。。

#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
vector<int>nums(n);
int average = 0;
int sum  = 0;
for(int i=0;i<n;i++){cin>>nums[i];sum += nums[i];}
average = sum/n;
cout<<sum<<" "<<average<<endl;
return 0;
}

输出米字型

在这里插入图片描述

解题思路

建立用于遍历八个方向的方向数组,通过中间的数不断循环向外扩散。

解题代码

#include<bits/stdc++.h>
using namespace std;
//记录八个方向用于遍历
const int dx[8] = {-1,1,0,0,-1,-1,1,1};
const int dy[8] = {0,0,-1,1,-1,1,-1,1};
int main(){
int n;
cin>>n;
//根据输入得出矩阵大小
int size = n*2-1;
vector<vector<char> >nums(size,vector<char>(size,'.'));
//记录中心坐标
int posx = nums.size()/2;
int posy = nums.size()/2;
nums[posx][posy] = 'A'+n-1;
//记录中心字符
char center = nums[posx][posy];
for(int i=1;i<n;i++){
//向八个方向扩散得出答案
    for(int j=0;j<8;j++){
        int x = posx + dx[j]*i;
        int y = posy + dy[j]*i;
        nums[x][y] = center - i;
    }
}
//输出答案
for(int i=0;i<size;i++){
    for (int j = 0; j < size; j++)
    {
        cout<<nums[i][j];
    }
    cout<<endl;
}
return 0;
}

排队打水问题

在这里插入图片描述

解题思路

这题乍一看说输出最短时间,结果看测试示例就明白,是每个人的等待最短时间相加。。。

这个等待时间相加很明显,先排个序,然后以水龙头的个数进行数据分组,比如水龙头有3个,则第一组是前三个最快时间的人,第二组是后三个…一直往后,但是对于每一个人来说它的等待时间是连续的,所以需要连续继承的相加,说太多浪费时间,建议这个时候自己思考,然后再看代码,不然可能不会的永远不会,会的永远都会。。。

解题代码

#include<bits/stdc++.h>
using namespace std;
int main(){
int n,r;
cin>>n>>r;
vector<int>time(n);
for(int i=0;i<n;i++)cin>>time[i];
//排序
sort(time.begin(),time.end());
int sum = 0;
for(int i=0;i<n;i++){
//一旦为第一组之后,开始继承前面的结果
    if(i>r-1){
        time[i]+=time[i-r];
    }
    sum += time[i];
}
cout<<sum<<endl;
return 0;
}

王、后传说

在这里插入图片描述

解题思路

这就是标准的n皇后问题,需要用到回溯法

我的解题过程

  1. 创建棋盘,更新国王的位置,并且根据八个方向把边上的位置也标记。
  2. 为基准,以回溯为方式向下放置皇后。
  3. 放置皇后之前需要判断是否可以放置皇后,可以通过check函数检查该位置的前面几行是否在上、左上、右上三个方向出现过皇后'Q',一旦出现则该位置不能放置(由于是以行为方式放置,所以左右不可能出现’Q’),当然这题还需要检查是否为国王位。
  4. 只要到达了最后一行的下一行(由于我是以0为初始,所以是row==n即可判断),则视为一次正确的棋盘皇后放置,答案更新一次。

可以看看之前的n皇后问题
n皇后问题

解题代码

#include<bits/stdc++.h>
using namespace std;
int n,w_x,w_y;
const int dx[8] = {-1,-1,-1,0,0,1,1,1};
const int dy[8] = {0,-1,1,1,-1,0,-1,1};
int res = 0;
bool check(vector<vector<char> >&board,int x,int y){
    //检查上方是否有皇后冲突
    for(int i=0;i<x;i++){
        if(board[i][y]=='Q')
            return false;
    }//检查右上方是否有皇后冲突
    for(int i=x-1,j=y+1;i>=0&&j<n;i--,j++){
        if(board[i][j]=='Q')
            return false;
    }//检查左上方
    for(int i=x-1,j=y-1;i>=0&&j>=0;i--,j--){
        if(board[i][j]=='Q')
            return false;
    }
    return true;
}
void dfs(vector<vector<char> > &board,int row){
    if(row==n){
        res++;
        return;
        }
    for(int i = 0;i<n;i++){
    //一旦该位置不能放置则continue到下个位置
        if(board[row][i]=='W'||!check(board,row,i))
            continue;
            //放置皇后
            board[row][i] = 'Q';
        dfs(board,row+1);
        	//撤销皇后
            board[row][i] = '.';
    }
}
int main(){
cin>>n>>w_x>>w_y;
vector<vector<char> >board(n,vector<char>(n,'.'));
board[w_x-1][w_y-1] = 'W';
//更新国王
for(int i=0;i<8;i++){
    int n_x = w_x-1+dx[i],n_y = w_y-1+dy[i];
    if(n_x>=0&&n_x<n&&n_y>=0&&n_y<n)
        board[n_x][n_y] = 'W';
}
dfs(board,0);
cout<<res;
return 0;
}

理财计划

在这里插入图片描述

题目就是找出数学迭代关系,通过循环迭代多次即可得到最终的存款,而后减去本金,便得到利益。

#include<bits/stdc++.h>
using namespace std;
double k,n,p,res;
int main(){
cin>>k>>n>>p;
double sum = 0;
for(int i=0;i<n;i++){
    sum += k;
    sum += sum*p;
}res = sum-k*n;
printf("%.2llf",res);
return 0;
}

以上是关于蓝桥杯练习赛5--全解析的主要内容,如果未能解决你的问题,请参考以下文章

2021.5.22 2022蓝桥杯练习赛3

2021.5.7 2022蓝桥杯练习赛1

2021.5.14 2022蓝桥杯练习赛2

蓝桥杯双非本科?大一大二不敢参加?这篇蓝桥全解析帮你打消疑虑轻松获奖内附蓝桥资源和学习路线

C语言课程设计——25道蓝桥杯练习题

蓝桥杯 基础练习 5-9