第十五届蓝桥杯模拟赛第二期C++

总的来说五个填空五个程序难度一般般,没有说上高难度的题。

        疯狂吐槽dev得不好用,ICPC已经上Clion了,Dev自动补充很不好,而且只支持C++11??? **了个狒狒的 啊啊啊啊难受!!!

吐槽完毕接下来开始正题

A:

小蓝要在屏幕上放置一行文字,每个字的宽度相同。 小蓝发现,如果每个字的宽为 36 像素,一行正好放下 30 个字,字符之间和前后都没有任何空隙。 请问,如果每个字宽为 10 像素,字符之间不包含空隙,一行可以放下多少个字?

        纯纯签到题。。。。。 口算 36*30/10 = 108   直接cout一下108就行。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    cout<<36*30/10<<endl;
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    
    //	system("pause"); //用于debug时打开
    return 0;
}

B:

求 2**2023%1000,即 2的2023次方除以1000的余数。

        这道题考察了大数的计算和表示,可以用string进行存储,也可以用快速幂,我在这用了 long double 类型计算看后3位数值。

//long double类型
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    long double a = 1;
    for (int k = 1; k <= 2023;k++){
        a *= 2;
    }

    printf("%.Lf\n", a);
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}
//string 类型存放数据
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    string number = "2";
    for (int i = 1; i < 2023; i++) {
        int temp = 0;
        for (int j = 0; j < number.size(); j++) {
            int base = number[j] - '0';
            base *= 2;
            if (temp >= 1) {
                base += temp;
                temp = 0;
            }
            if (base >= 10) {
                if (j == number.size() - 1) {
                    temp = base / 10;
                    base %= 10;
                    number[j] = (char)(base + '0');
                    number += to_string(temp);
                    break;
                }
                else {
                    temp = base / 10;
                    base %= 10;
                }
            }
            number[j] = (char)(base + '0');
        }
    }
    reverse(number.begin(), number.end());
    cout << number << endl;
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    //	system("pause"); //用于debug时打开
    return 0;
}
//快速幂
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

int qmi(int a,int b){
	int res = 1;
	while(b) {
		if(b&1){ 
            res=(res*a)%1000;
        }   
		b >>= 1;
		a = a * a % 1000;
	}
	return res % 1000;
}

void solve(){
    cout << qmi(2, 2023) << endl;
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}

C:

如果一个正整数转化成二进制与转换成八进制后所有数位的数字之和相等,则称为数位和相等的数。前几个数位和相等的正整数为 1, 8, 9, 64, …… 请问第 23 个数位和相等的正整数是多少?

        最基本的进制转化题,将十进制数分别转化为2进制和8进制数,在将其转化为字符串,对每位求和。。。。简单题给个代码看看吧。(在二进制的时候直接用库里的函数方便好用!!!)

        注: bitset<8>bit(5) 将5转化为8位二进制数,变量名为bit

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
//3

string tooct(int d){
    string s = "";
    string t = "01234567";
	int x;
	if(d == 0) {
        return to_string(0);
    }
	while(d) {
		x = d%8;
        s = t[x] + s;
        d /= 8;
	}
	return s;
}

bool check(string s1,string s2){
    ll num1 = 0;
    ll num2 = 0;
    for(auto a:s1){
        num1 += a - '0';
    }
    for(auto a:s2){
        num2 += a - '0';
    }
    if(num1==num2){
        return true;
    }else{
        return false;
    }
}

void solve() {
    int count = 0;
    for (int i = 1; i < 1000000;i++){
        bitset<64> bit(i);
        string s2 = bit.to_string();
        auto s8 = tooct(i);
        if(check(s2,s8)){
            count++;
            if(count==23){
                cout << i << endl;
                break;
            }
        }
    }
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}

D:

对于以下这些数(6行,每行6个,共36个),请问约数个数最多的是哪个?(如果有多个,请回答出现最早的那个)

393353 901440 123481 850930 423154 240461

373746 232926 396677 486579 744860 468782

941389 777714 992588 343292 385198 876426

483857 241899 544851 647930 772403 109929

882745 372491 877710 340000 659788 658675

296521 491295 609764 718967 842000 670302

        签到提不想说了。。。一共36个数据,直接模拟就行,统计每个数的约数个数。

        注意:求约数减少运算枚举到根号i就行

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve(int index ,int a) {
    int cont = 0;
    for (int i = 1; i * i <= a;i++){
        if(a%i==0){
            cont++;
        }
    }
    cout << index << " " << cont << endl;
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 36;
    int i = 1;
    while(t--){
        int a;
        cin >> a;
        solve(i++,a);
    }
    
//	system("pause"); //用于debug时打开
    return 0;
}
901440

E:

小蓝有一个01矩阵。他打算将第一行第一列的 0 变为 2 。变化过程有传染性,每次 2 的上下左右四个相邻的位置中的 0 都会变成 2 。直到最后每个 2 的周围都是 1 或 2 结束。请问,最终矩阵中有多少个 2 ?以下是小蓝的矩阵,共 30 行 40 列。

0000100010000001101010101001001100000011

0101111001111101110111100000101010011111

1000010000011101010110000000001011010100

0110101010110000000101100100000101001001

0000011010100000111111001101100010101001

0110000110000000110100000000010010100011

0100110010000110000000100010000101110000

0010011010100110001111001101100110100010

1111000111101000001110010001001011101101

0011110100011000000001101001101110100001

0000000101011000010011111001010011011100

0000100000011001000100101000111011101100

0010110000001000001010100011000010100011

0110110000100011011010011010001101011011

0000100100000001010000101100000000000010

0011001000001000000010011001100101000110

1110101000011000000100011001001100111010

0000100100111000001101001000001010010001

0100010010000110100001100000110111110101

1000001001100010011001111101011001110001

0000000010100101000000111100110010101101

0010110101001100000100000010000010110011

0000011101001001000111011000100111010100

0010001100100000011000101011000000010101

1001111010010110011010101110000000101110

0110011101000010100001000101001001100010

1101000000010010011001000100110010000101

1001100010100010000100000101111111111100

1001011010101100001000000011000110110000

0011000100011000010111101000101110110001

         开始有点水平了,两种方法,一种BFS,第二种更便捷(***),先遍历0的个数,减掉不可能为2的0的个数(四条边的0单独看,被1包围的0不可能变成2),结果就出来了。excel里全部替换就能统计出0的个数。结果为

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int cont = 0;
//5 题
struct node {
    node(int a,int b){
        x = a;
        y = b;
    }
    int x;
    int y;
};

bool vis[35][45];
char map_[35][45];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};


void bfs(int x,int y) {
	queue<node> q;
    q.push(node(x, y));
    while(!q.empty()) {
		auto t=q.front();
		q.pop();
		map_[t.x][t.y]='2';
		cont++;
		for(int i=0;i<4;i++) {
            int a = t.x + dx[i];
            int b = t.y + dy[i];
            if(a<0||b<0||a>29||b>39) {
                continue;
            }
			if(map_[a][b]!='0') {
                continue;
            }	
			map_[a][b]='2';
			q.push(node(x,y));
		}
	}
}


void solve() {
    for (int i = 0; i < 30;i++){
        for (int j = 0; j < 40;j++){
            cin >> map_[i][j];
        }
    }
    bfs(0, 0);
    cout << cont << endl;
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}

F:

给定一个正好六位的正整数 x,请将 x 循环左移一位后输出。所谓循环左移一位,是指将原来的十万位变为个位,原来的万位到个位向左移动依次变为十万位到十位。例如:194910 左移一位变为 949101 。又如:987123 左移一位变为 871239 。

        总共就6位数字,签到题。两种方法:

//第一种,接收类型字符串,从第二个字符开始求余输出。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    string s;
    cin>>s;
    for(int i=1;i<=s.size();i++){
        cout<<s[i%s.size()];
    }
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}
//第二种:int类型,求出每一位的数值存放在数组中,按4 3 2 1 0 5的下标顺序输出
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    int number;
    cin >> number;
    int vect[6] = {0};
    int i = 0;
    while(number){
        vect[i++] = number % 10;
        number /= 10;
    }
    cout << vect[4] << vect[3] << vect[2] << vect[1] << vect[0] << vect[5] << endl;
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}

G:

输入一个仅包含小写英文字母的字符串,请问这个字符串中的最后一元音是什么。在英文中,a, e, i, o, u 共 5 个字母是元音字母,其它字母不是元音字母。

输入格式

  输入一行包含一个字符串,仅由小写英文字符组成,字符串中至少包含一个元音字母。

输出格式

  输出一行包含一个字符,表示答案。

样例输入

lanqiao

样例输出

o

样例输入

cup

样例输出

u

        欸不说了直接上代码。。。从后开始遍历

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    string s;
    cin >> s;
    for (int i = s.size() - 1; i >= 0;i--){
        if(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u'){
            cout << s[i] << endl;
            break;
        }
    }
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}

H:

给定一个整数,对这个整数的一次转换是指将这个整数变为这个整数的所有数位上的非零数字的乘积。例如,对 123456789 进行一次转换变为 123456789=362880,再进行一次转换变为 36288=2304,再进行一次转换变为 234=24,再进行一次转换变为 8。给定一个整数,请依次将转换过程中经历的每个整数输出,直到小于 10 。

输入格式

  输入一行包含一个整数 n 。

输出格式

  输出多行,每行包含一个整数。

样例输入

123456789

样例输出

362880

2304

24

8

        依旧是对每位数的处理,不多说看代码。。。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

ll tran(string s){
    ll ans = 1;
    for (int i = 0; i < s.size();i++){
        if(s[i]!='0'){
            ans *= (ll)(s[i] - '0');
        }
    }
    return ans;
}

void solve() {
    ll a;
    cin >> a;
    while(a>=10){
        string s = to_string(a);
        a = tran(s);
        cout << a << endl;
    }
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}

I:

小蓝站在一个 n 行 m 列的方格图中间,方格图的每一个方格上都标有一个正整数。如果两个相邻方格(上下左右四个方向相邻)内的数的最大公约数大于 1 ,则可以从其中一个方格移动到另一个方格,当然也可以从另一个方格移回第一个方格。假设小蓝开始时站在第 r 行第 c 列,请问小蓝可以移动到方格图内的多少个方格?

输入格式

  输入的第一行包含两个整数 n, m ,用一个空格分隔,表示方格图的行数和列数。接下来 n 行,每行包含 m 个正整数,相邻整数间用一个空格分隔,依次表示方格图中从第 1 行到第 n 行,每行从第 1 列到第 m 列中的数。接下来一行包含两个整数 r, c,用一个空格分隔,表示小蓝所在的行号和列号。

输出格式

  输出一行包含一个整数,表示答案。

样例输入

3 4

3 6 5 5

2 4 3 5

7 8 3 8

3 2

样例输出

5

        欸开始有点水平了,经典的DFS深搜就可以了,但数据量我不能确定能过多少???等结果出来吧。上代码。

接收图的数据就不多说了,从x,y开始搜,访问过的标记为1,初始化方格个数为1。

然后对四个方向进行枚举,其中最大公约数gcd需要自己定义,(吐槽蓝桥才支持C++11,也不是linux,不能使用__gcd(),也不能像在C++17中直接用gcd() !!!dev调试还那么waste)我**了个******(骂的很脏)

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

int map_[105][105];
int vis[105][105];
int n, m;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

bool in(int x1, int y1, int x2, int y2) {
    return x1 >= 0 && x1 < n && y1 >= 0 && y1 < m &&
        x2 >= 0 && x2 < n && y2 >= 0 && y2 < m &&
        gcd(map_[x1][y1], map_[x2][y2]) > 1;
}

bool not_in(int nx,int ny){
    return nx < 0 || nx >= n || ny < 0 || ny >= m || vis[nx][ny];
}

int dfs(int x, int y) {
    if (not_in(x,y)) {
        return 0;
    }
    vis[x][y] = 1;
    int count = 1;
    for (int i = 0; i < 4; i++) {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if (in(x, y, xx, yy)) {
            count += dfs(xx, yy);
        }
    }
    return count;
}
int Begin(int pox, int poy) {
    return dfs(pox - 1, poy - 1);
}
void solve() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> map_[i][j];
        }
    }
    int x, y;
    cin >> x >> y;
    int ans = Begin(x, y);
    cout << ans << endl;
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}

回到正题:

J:

给定一个序列 a[1], a[2], …, a[n] 和一个整数 k,请找出一个长度正好为 k 的区间,使得区间中所有数的和最大。即要找到一个整数 p ,使得 1 <= p 且 p+k-1 <= n ,使得 a[p]+a[p+1]+…+a[p+k-1] 最大。

输入格式

  输入的第一行包含两个整数 n , k。第二行包含 n 个整数,相邻的整数之间使用一个空格分隔,表示给定的序列。

输出格式

  输出一行包含一个整数,表示最大的区间和,你只需要输出和就行,不需要输出方案。

样例输入

6 3

2 3 9 1 9 5

样例输出

19

        这个题作为最后一题很不应该!前缀和解决问题。。。不过多地说(注意一下数据类型就好)

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    int n, k;
    cin >> n >> k;
    vector<ll> num(n + 5, 0);
    for (int i = 1; i <= n;i++){
        cin >> num[i];
        num[i] += num[i - 1];
    }
    ll ans = 0;
    for (int i = k; i <= n;i++){
        ll temp = num[i] - num[i - k];
        ans = max(ans, temp);
    }
    cout << ans << endl;
}

int main() {
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();

//	system("pause"); //用于debug时打开
    return 0;
}

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值