蓝桥杯模拟题一

选择题

编程题

第一题

使用桶去统计每个字母个数

#include<iostream>
using namespace std;

// 素数判断
bool is_prime(int n){
	if(n <= 1) return false; // 0和1都不是素数
	for(int i = 2; i <= n / i; i ++ ){
		if(n % i == 0) return false;
	}
	return true;
}

int main(){
	char c[200];
	cin >> c;
	// 统计字母个数, 0下标记录'a'的个数, 1下标记录'b'的个数,..., 25下标记录'z'的个数 
	int bucket[30] = {};
	for(int i = 0; c[i]; i ++ ){
		bucket[c[i] - 97] ++ ;
	}
	// 查找最大值和最小值, 最小值查找时要注意跳过0
	int Max = 0, Min = 200;
	for(int i = 0; i < 26; i ++ ){
		if(bucket[i] == 0) continue;
		Max = max(Max, bucket[i]);
		Min = min(Min, bucket[i]);
	}
	
	if(is_prime(Max - Min)) cout << "Yes";
	else cout << "No";
	return 0;
}

第二题

高精度加法模板题

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

// 高精度加法
vector<int > add(vector<int > &a, vector<int > &b){
	vector<int > c;
	int t = 0; // 记录是否有进位
	for( int i = 0; i < a.size() || i < b.size() ; i ++ ){
		if( i < a.size() ) t += a[i];
		if( i < b.size() ) t += b[i];
		c.push_back(t % 10); // 当前个位存进数组中
		t /= 10; 
	}
	if(t) c.push_back(t); // 判断最高位是否有进位
	return c;
}

int main(){
	// 高精度输入
	string A,B,C;
	cin >> A >> B >> C;
	// 数组逆序存储输入数字
	vector<int > a, b, c;
	for( int i = A.size() - 1; i >= 0; i -- ) a.push_back(A[i] - '0');
	for( int i = B.size() - 1; i >= 0; i -- ) b.push_back(B[i] - '0');
	for( int i = C.size() - 1; i >= 0; i -- ) c.push_back(C[i] - '0');
	
	auto ans = add(a,b); // ans = a + b;
	ans = add(ans, c); // ans = ans + c;
	
	for( int i = ans.size() - 1; i >= 0; i --) printf("%d",ans[i]);
	return 0;
}

第三题

贪心+覆盖问题
贪心点:从半径大的从大到小进行选取
本题保证 2 < R i < 15 2 < R_i < 15 2<Ri<15,故对于宽度的覆盖不用进行考虑,只需要对该喷水装置放进去后长度的覆盖进行考虑即可。
i i i 个喷水装置能够覆盖的长度为: l i = ( R i 2 − 2 2 ) l_i = \sqrt{(R_i^2 - 2^2)} li=(Ri222)

在这里插入图片描述

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

double l[700];

bool cmp(double a, double b){
    return a > b;
}

int main(){
    int n;
    cin >> n;
    for(int i = 1; i <= n; i ++ ){
        double r;
        cin >> r;
        l[i] = sqrt(r * r - 2 * 2); // 计算覆盖的长度
    }
    sort(l + 1, l + n + 1, cmp); // 从大到小排序
    double s = 0; // 计算覆盖总长度
    bool flag = false; // 假设不能完全覆盖
    for(int i = 1; i <= n; i ++ ){
        s += 2 * l[i]; // 左右长度
        if(s >= 40){
            cout << i << endl; // 输出需要喷水装置个数
            flag = true; // 能够完全覆盖
            break;
        }
    }
    if(!flag) cout << "NULL" <<endl;
    return 0;
}

第四题

全排列+完全错排+乘法原理
每行数字不同:完全错排
每列数字不同:全排列

#include<iostream>
using namespace std;
// 用 ll 代替 long long
typedef long long ll;
// 全排列
ll arrange(int n){
	ll s = 1;
	for(int i = 1; i <= n; i ++ ){
		s *= i;
	}
	return s;
}
// 完全错排
ll literal(int n){
	ll f[20];
	f[1] = 0, f[2] = 1;
	for(int i = 3; i <= n; i ++ ){
		f[i] = (i - 1) * f[i - 2] + (i - 1) * f[i - 1];
	}
	return f[n];
}

int main(){
	int n;
	cin >> n;
	cout << arrange(n) * literal(n);
	return 0;
}

第五题

该问题为01背包问题,但实际问题数据量较小,物品数量最多30,所以可以使用递归。

#include<iostream>
using namespace std;

int weight[40];
int v, n;
int ans; // 记录答案

// 函数定义为前dep-1个物品, 能凑出的体积为total
void dfs(int dep, int total){
	ans = min(ans, v - total); // 每次有新的体积产生时, 更新答案
	if(dep > n) return; // 物品已经取完
	
	if(total + weight[dep] <= v) dfs(dep + 1, total + weight[dep]); // 取第dep个物品, 保证不超过箱子容量
	dfs(dep + 1, total); // 不取第dep个物品
	return;
}

int main(){
	cin >> v >> n;
	ans = v;
	for(int i = 1; i <= n; i ++ ){
		cin >> weight[i];
	}
	dfs(1, 0);
	cout << ans << endl;
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值