第十三届蓝桥杯省赛第一场个人题解(2022年)

目录

      • 试题 A: 九进制转十进制(5分)
      • 试题 B: 顺子日期(5分)
      • 试题 C: 刷题统计(10分)
      • 试题 D: 修剪灌木(10分)
      • 试题 E: X 进制减法(15分) dfs出来了!万岁
      • 试题 F: 统计子矩阵(15分)

试题 A: 九进制转十进制(5分)

第十三届蓝桥杯省赛第一场个人题解(2022年)_第1张图片
答案:

1478

代码:

#include
using namespace std;
int main(){
	long long  ans = 2*1+2*9+0*pow(9,2)+2*pow(9,3);
	cout<<ans; 
	return 0;
} 

试题 B: 顺子日期(5分)

【问题描述】
小明特别喜欢顺子。顺子指的就是连续的三个数字:123、456 等。顺子日期指的就是在日期的 yyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123; 而 20221023 则不是一个顺子日期,它一个顺子也没有。小明想知道在整个 2022年份中,一共有多少个顺子日期。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分

想法:这个题有个槽点 就是012算不算顺子呐?

答案(算零):

14

不算:

4

代码1:(0要算)

#include
using namespace std;
int dt[15] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int f[5];
bool check(){
	for(int i = 2; i <=3;i++){
		if(f[i-1]+1==f[i]&&f[i]+1==f[i+1]) return true;
	}
	return false;
}
int main(){
	int ans = 0;
	for(int i = 1; i<= 12;i++){
		for(int j = 1; j <= 31;j++){
			f[1]= 0,f[2]=0,f[3]=0,f[4]=0;
			if(j<=dt[i]){
				if(i>=10){
					f[1] = i/10; f[2] = i%10;
				}else f[2] = i%10;
				
				if(j>=10){
					f[3] = j/10; f[4] = j%10;
				}else f[4] = j%10; 
				if(check()) ans++;
			}
		}
	}
	cout<<ans;
	return 0;
} 

代码(不算0):

#include
using namespace std;
int dt[15] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int f[5];
bool check(){
	for(int i = 2; i <=3;i++){
		if(f[i-1]+1==f[i]&&f[i]+1==f[i+1]&&f[i-1]&&f[i]&&f[i+1]) return true;
	}
	return false;
}
int main(){
	int ans = 0;
	for(int i = 1; i<= 12;i++){
		for(int j = 1; j <= 31;j++){
			f[1]= 0,f[2]=0,f[3]=0,f[4]=0;
			if(j<=dt[i]){
				if(i>=10){
					f[1] = i/10; f[2] = i%10;
				}else f[2] = i%10;
				
				if(j>=10){
					f[3] = j/10; f[4] = j%10;
				}else f[4] = j%10; 
				if(check()) ans++;
			}
		}
	}
	cout<<ans;
	return 0;
} 

试题 C: 刷题统计(10分)

第十三届蓝桥杯省赛第一场个人题解(2022年)_第2张图片
输入样例:

10 20 99

输出样例:

8

在这里插入图片描述
想法:我当时想的是先写个暴力 然后再一周一周的算?压缩一下循环
结果没有时间了 啊啊啊

代码:(估计水不完)

#include
using namespace std;
int main(){
	long long a,b,n;
	cin>>a>>b>>n;
	long long sum = 0,cnt = 0;
	while(sum<n){
		for(int i = 1; i <= 7;i++){
			if(i>5) sum += b,cnt++;
			else sum += a,cnt++;
			if(sum>=n){
				cout<<cnt;
				return 0;
			}
		}
	}
	
	return 0;
}

试题 D: 修剪灌木(10分)

第十三届蓝桥杯省赛第一场个人题解(2022年)_第3张图片
输入样例:

3

输出样例:

4
2
4

在这里插入图片描述
代码:(这个题应该不会超时)

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

试题 E: X 进制减法(15分) dfs出来了!万岁

【问题描述】
进制规定了数字在数位上逢几进一。
X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则X 进制数 321 转换为十进制数为 65。
现在有两个 X 进制表示的整数 A 和 B,但是其具体每一数位的进制还不确定,只知道 A 和 B 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。请你算出 A A B 的结果最小可能是多少。
请注意,你需要保证 A 和 B 在 X 进制下都是合法的,即每一数位上的数字要小于其进制。
【输入格式】
第一行一个正整数 N,含义如题面所述。
第二行一个正整数 Ma,表示 X 进制数 A 的位数。
第三行 Ma 个用空格分开的整数,表示 X 进制数 A 按从高位到低位顺序各
个数位上的数字在十进制下的表示。
第四行一个正整数 Mb,表示 X 进制数 B 的位数。
第五行 Mb 个用空格分开的整数,表示 X 进制数 B 按从高位到低位顺序各
个数位上的数字在十进制下的表示。
请注意,输入中的所有数字都是十进制的。
【输出格式】
输出一行一个整数,表示 X 进制数 A-B 的结果的最小可能值转换为十进
制后再模 1000000007 的结果。
第十三届蓝桥杯省赛第一场个人题解(2022年)_第4张图片

输入样例:

11
3
10 4 0
3
1 2 0

输出样例:

94

思想:
我现在觉得这个题好恶心啊! 妈耶当时写好再调试好 花了差不多两个小时 妈呀
最后dfs出来了 呜呜好棒 但是但是但是 好像没有取模 寄

代码:

#include
using namespace std;
int n,ma,mb,ans = 99999999;
int a[100005];
int b[100005];
void dfs(int x,int y,int sa,int sb,int sum){//两个数位  权值ji
	if(x==ma&&y==mb){
		ans = min(ans,sa-sb);
		return;
	}else{
		for(int i = 2; i <=n;i++){ //n是最大倍数
		 
 			if(a[x]>=i||b[x]>=i) continue;  //剪枝 
 			
 			sum *= i;
			sa += a[x+1]*sum; sb += b[y+1]*sum;
			dfs(x+1,y+1,sa,sb,sum);
			
			sa -= a[x+1]*sum; sb -= b[y+1]*sum;
			sum /= i;
		}
	}
}
int main(){
	cin>>n;
	cin>>ma;
	for(int i = ma; i >=1;i--) cin>>a[i];
	cin>>mb;
	for(int i = mb; i >= 1;i--) cin>>b[i];
	dfs(1,1,a[1],b[1],1);
	cout<<ans;
	return 0;
}

搜索的时候 也 不太好取模啊 不想调了 估计不行

#include
using namespace std;
int n,ma,mb;
int a[100005];
int b[100005];
typedef long long ll;
const ll mod = 1000000007;
ll ans = 99999999;

void dfs(int x,int y,ll sa,ll sb,ll sum){//两个数位  权值ji
	if(x==ma&&y==mb){
		ans = min(ans,(sa%mod-sb%mod)%mod);
		//cout<<"................."<
		//cout<<"xy: "<
		return;
	}else{
		for(int i = 2; i <=n;i++){ //n是最大倍数
		 
 			if(a[x]>=i||b[x]>=i) continue;  //剪枝 
			//cout<<"be: "<
 			sum *= i;
			sa += a[x+1]*sum; sb += b[y+1]*sum;
			dfs(x+1,y+1,sa,sb,sum);
			sa -= a[x+1]*sum; sb -= b[y+1]*sum;
			sum /= i;
		}
	}
}
int main(){
	cin>>n;
	cin>>ma;
	for(int i = ma; i >=1;i--) cin>>a[i];
	cin>>mb;
	for(int i = mb; i >= 1;i--) cin>>b[i];
	dfs(1,1,a[1],b[1],1);
	cout<<ans;
	return 0;
}

试题 F: 统计子矩阵(15分)

第十三届蓝桥杯省赛第一场个人题解(2022年)_第5张图片
输入样例:

3 4 10
1 2 3 4
5 6 7 8
9 10 11 12

输出样例:

19

【样例说明】
满足条件的子矩阵一共有 19,包含:
大小为 1 × 1 的有 10 个。
大小为 1 × 2 的有 3 个。
大小为 1 × 3 的有 2 个。
大小为 1 × 4 的有 1 个。
大小为 2 × 1 的有 3 个。
第十三届蓝桥杯省赛第一场个人题解(2022年)_第6张图片
思想 : 直接二维前缀和 but 我好像写错了

你可能感兴趣的:(ACM,蓝桥杯,算法题与坑,蓝桥杯,c++)