第十三届蓝桥杯软件类省赛C/C++大学B组

【前文速览】

顺子日期,题意不明,我是把012也当成顺子,且没算逆序。
统计子矩阵,二维前缀和暴力。
积木画,状压dp。
扫雷,暴力模拟。
李白打酒加强版,dp或者记忆化搜索。
砍竹子,赛时暴力,赛后想到用优先队列蛮好搞的。

A:九进制转十进制

在这里插入图片描述
【我的答案】

1478

【参考程序】

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

int main()
{
   
	string s = "2022";
	int res = 0;
	for(auto x : s){
   
		res = res * 9 + x - '0';
	}
	cout << res << endl;
	
	return 0;
} 

B:顺子日期

在这里插入图片描述

【分析】

本题题面存在一定的歧义,首先顺子没有说明是否可以包含0,其次没有强调是否包含逆序顺。如果不能包含0,那么210不是顺子,不能证明321不是顺子。
不知道这个题目最后怎么评判。
按照我的理解,012算做顺子,第二个例子排除了逆序顺的情况,因此年份不可能组成234的顺子,只需要考虑月份和日期,构造成对应格式的字符串加以判断即可。

【我的答案】

14

【参考程序】

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

int Day[] = {
   0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int year = 2022, month = 1, day = 1;

bool HaveShunZi(string str)
{
   
	if(str[2] == str[1] + 1 && str[1] == str[0] + 1) return true;
	if(str[3] == str[2] + 1 && str[2] == str[1] + 1) return true;
	return false;
}

int main()
{
   
	int cnt = 0;
	while(month <= 12 && day <= Day[month]){
   
		string str = "";
		
		str += month / 10 + '0';
		str += month % 10 + '0';
		str += day / 10 + '0';
		str += day % 10 + '0';
		if(HaveShunZi(str)) cnt++;
		
		day++;
		if(day > Day[month]){
   
			month++;
			day = 1;
		}
	}
	cout << cnt << endl;
	
	return 0;
} 

C:刷题统计

在这里插入图片描述

【参考程序】

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

typedef long long LL;

int main()
{
   
	LL a, b, n;
	cin >> a >> b >> n;
	LL weekwork = 5 * a + 2 * b;
	LL t = n / weekwork * 7;
	LL work = n / weekwork * weekwork;
	while(work < n){
   
		if(t % 7 < 5) work += a;
		else work += b;
		t++;
	}
	cout << t << endl;
	
	return 0;
} 

D:修剪灌木

在这里插入图片描述

【分析】

我考虑了三种情况:
第一次访问,访问到最右端再返回访问,访问到最左端再返回访问。
存在一定冗余,计算后两者取最大值即可。

【参考程序】

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

int main()
{
   
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++){
   
		//cout << i << ' ' << 2 * (n - i) << ' ' << 2 * (i - 1) << endl;
		cout << max(i, max(2 * (n - i), 2 * (i - 1))) << endl;
	}
	
	return 0;
} 

E:X进制减法

在这里插入图片描述
在这里插入图片描述

【分析】

这个题目考察大家对于进制的理解是否深刻。以前习惯了数位进制都相同的表示,所以想当然的联想到指数表示法,即X进制每一位权重从低到高分别是X的[0, 1, 2, …… , n - 1]次方。
其实本质上,每一位的权重应该是所有低位进制的乘积。可以这么理解,低位满了才会产生进位。而当前位的进制,决定了当前位满多少会产生下一位的进位,这里面是乘法的关系。
因为A≥B,对于每一位的进制,有三个限制:
①最小是2;②必须比A和B在该位上的数值大;③不超过N。
从最低位开始看,每一位的选取都可以分解为该位进制和后面数的乘积,最终结果非负,因此越小越好,题目保证合法,因此不用考虑N的限制。
代码有点丑,其实直接用数组就行了,可以省去很多判断,如果A的位数比B多,就把B的那些位当成0来处理。

【参考程序】

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

const int mod = 1000000007;

typedef long long LL; 

vector<int> A, B;

int main()
{
   
	int n;
	cin >> n;
	int Ma, Mb;
	cin >> Ma;
	for(int i = 1; i <= Ma; i++){
   
		int x
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值