蓝桥杯真题练习---2022年B组

 第一题

本题非常简单 但多次ac不过 注意数据范围 在暴力的基础上要注意优化算法  非数据量特别小的题肯定会卡一部分超时 多注意语句是否有遗漏 比赛不会直接出结果 不方便找bug 本题在ac过程中多次缺少一些语句 思路简单 代码残缺

#include<iostream>
using namespace std;
typedef long long ll;
ll a, b, goal;
int main(){
	cin >> a >> b >> goal;
	
	ll sum = a * 5 + b * 2;
	ll count = goal / sum;//先将刷题数降到一周以内 减少循环次数 否则会超时
	goal = goal % sum;
	
	int ans = 0;//本周需要刷多少天 
	if(goal % sum != 0)
		for(int i = 1; ; i = i % 7 + 1){
			if(i <= 5)
				goal -= a;
			else
				goal -= b;
			ans ++;
			if(goal <= 0)
				break;
		}
		
	cout << ans + count * 7;
	
	return 0;
}

 第二题

遇到该类模拟题 建议直接推导公式 模拟几种情况 可以得出 N棵左边的树最高可以长到(n - i)* 2

右边的树最高可以长到(i - 1) * 2  注意答案格式 会换行输出还是空格输出 千万注意

#include<iostream>
using namespace std;
int main(){
	int n;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		if(i <= n / 2)	
			cout << (n - i) * 2 << endl;
		else 
			cout << (i - 1) * 2 << endl;
	}
	
	return 0;
}

第三题

题意理解起来都费劲

321 ---> 65 的转变过程

首先题目解释了进制的含义 逢几进一  2 可以看作个位二进制下逢2进1进上来的 因此 这个2的十进制表示就是2 * 2 = 4  3可以看作第二数位逢十进一进上来的 3 = 3 * 10 * 2 = 60 而个位数1 就代表1即可 总和为65

题解 针对蓝桥杯此题存在两道特殊测试点 A > B 但是ma < mb 即A的位数少于B 因此权值累加的步骤下要取二者长度较大的一个

注意读取数据时的形式 可以借鉴 省得再转置数组 或 从尾部下标向前导

简单来说不难 要注意的点比较多 一是注意计算每一步都要取模 说不定哪个测试数据就爆了

/*
简便的一种方法 直接计算每一位的差值 累加求和 
*/
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 1e7;
const int mod = 1000000007;
int A[N], B[N];
ll ans = 0;
int main(){
	int n;
	cin >> n;
	
	//从低位到高位正好与下标对应 
	int ma, mb;
	cin >> ma;
	for(int i = ma; i >= 1; i --)
		scanf("%d", &A[i]);
	cin >> mb;
	for(int i = mb; i >= 1; i --)
		scanf("%d", &B[i]);
	
	//位权用cnt进行累加记录 
	ll cnt = 1;
	int size = max(ma, mb);
	for(int i = 1; i <= size; i ++){
		//直接计算每一位的差值 
		ans += (((A[i] - B[i]) * cnt) % mod);
		ans %= mod; 
		cnt = (cnt * max(max(A[i], B[i]) + 1, 2)) % mod;
	}
	
	if(ans < 0)
		ans = (ans + mod) % mod;
		 
	cout << ans;
	
	return 0;
}
/*
较麻烦的一种方法 首先计算每位的位权 再分别计算出A B(取模后的值) 最后进行运算 
*/
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 1e7;
const int mod = 1000000007;
int A[N], B[N];
ll ans = 0, weight[N], a, b;
int main(){
	int n;
	cin >> n;
	
	//从低位到高位正好与下标对应 
	int ma, mb;
	cin >> ma;
	for(int i = ma; i >= 1; i --)
		scanf("%d", &A[i]);
	cin >> mb;
	for(int i = mb; i >= 1; i --)
		scanf("%d", &B[i]);
	
	//位权从最低位开始 weight[1]存 1 
	ll cnt = 1;
	weight[1] = 1;//j 最小到 1 最高位位权计算时不需要包含它本身的进制 无需到 0  
	int size = max(ma, mb);
	for(int i = 2; i <= size; i ++){
		//计算次位的进制 
		cnt = max(max(A[i - 1], B[i - 1]) + 1, 2);
		//前缀和思想存储权值 避免循环 
		weight[i] = (cnt * weight[i - 1]) % mod;
	}
	
	//计算 A
	for(int i = 1; i <= ma; i ++){
		a += (A[i] * weight[i]);
		a %= mod; 
	} 
	
	//计算 B
	for(int i = 1; i <= mb; i ++){
		b += (B[i] * weight[i]);
		b %= mod; 
	} 
	
	//避免出现负数 a取模后小于b 
	ans = (a - b + mod) % mod;
	
	cout << ans;
	
	return 0;
}

第四题 统计子矩阵

思路 本来想的是深搜枚举所有子矩阵 后来发现这根本没办法搜 

半正解是二维前缀和 四重循环枚举子矩阵的和 

正解是一维前缀和+滑动双指针 理解不了

/*
披着深搜的皮 实际应该不能用深搜模拟出来 前缀和登场 
*/
#include<iostream>
using namespace std;
const int N = 1000;
typedef long long ll;
int n, m, K, ans;
int num[N][N], sum[N][N]; 
int main(){
	scanf("%d %d %d", &n, &m, &K);
	for(int i = 1; i <= n; i ++){
		for(int j = 1; j <= m; j ++){
			scanf("%d", &num[i][j]);
			sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + num[i][j]; 
		}
	}

	ll all = 0;
	for(int i = 1; i <= n; i ++){
		for(int k = i; k <= n; k ++){
			for(int j = 1; j <= m; j ++){
				for(int l = j; l <= m; l ++){
					all = sum[k][l] - sum[i - 1][l] - sum[k][j - 1] + sum[i - 1][j - 1];
					if(all <= K)
						ans ++;
					else
						break;
				}
			}
		}
	} 
	
	cout << ans;
	return 0;
}

能拿点是点

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值