[蓝桥杯 2022 省 B] X 进制减法

148 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

[蓝桥杯 2022 省 B] X 进制减法

题目描述

进制规定了数字在数位上逢几进一。

XX 进制是一种很神奇的进制,因为其每一数位的进制并不固定!例如说某种 XX 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则 XX 进制数 321 转换为十进制数为 65

现在有两个 XX 进制表示的整数 AABB,但是其具体每一数位的进制还不确定,只知道 AABB 是同一进制规则,且每一数位最高为 NN 进制,最低为二进制。请你算出 ABA-B 的结果最小可能是多少。

请注意,你需要保证 AABBXX 进制下都是合法的, 即每一数位上的数字要小于其进制。

输入格式

第一行一个正整数 NN,含义如题面所述。

第二行一个正整数 MaM_{a},表示 XX 进制数 AA 的位数。

第三行 MaM_{a} 个用空格分开的整数,表示 XX 进制数 AA 按从高位到低位顺序各个数位上的数字在十进制下的表示。

第四行一个正整数 MbM_{b},表示 XX 进制数 BB 的位数。

第五行 MbM_{b} 个用空格分开的整数,表示 XX 进制数 BB 按从高位到低位顺序各个数位上的数字在十进制下的表示。

请注意,输入中的所有数字都是十进制的。

输出格式

输出一行一个整数,表示 XX 进制数 ABA-B 的结果的最小可能值转换为十进制后再模 10000000071000000007(即 109+710^9+7)的结果。

样例 #1

样例输入 #1

11
3
10 4 0
3
1 2 0

样例输出 #1

94

提示

【样例说明】

当进制为:最低位 22 进制, 第二数位 55 进制, 第三数位 1111 进制时, 减法得到的差最小。此时 AA 在十进制下是 108108BB 在十进制下是 1414,差值是 9494

【评测用例规模与约定】

对于 30%30 \% 的数据,N10,Ma,Mb8N \leq 10,M_{a}, M_{b} \leq 8.

对于 100%100 \% 的数据,2N1000,1Ma,Mb105,AB2 \leq N \leq 1000,1 \leq M_{a}, M_{b} \leq 10^5,A \geq B

蓝桥杯 2022 省赛 B 组 E 题。

分析

这题怎么说呢,QAQ,是我去年蓝桥杯比赛时候的一道题,我当时比赛时候题目都没看懂,只能说有点遗憾啦,今天在看了y总讲解之下,再加上bcjjj帮助debug,终于在萨个小时之后把这题给写出来了(其实是个不难的题目),奈何我现在实力还是不行。

1

首先,这题第一重要的点就是要把X进制数转十进制数的转化方法给学会了,其实去年和今年这时候我这题不会写的原因都在于我没看懂怎么转化,y总交了个很好的方法,对于题给数字321,转化为65的方法其实就是从最低位开始,每读一位,将这位上的数字变成0,然后看从最后一位数到这一位要数多少个数字。

2022-11-24 (2).png 这样,我们其实已经掌握了将一个X进制数字转化为十进制数的办法,我们可以推出公式,假设一个X进制数有nn位,从最高位到最低位的进制第ii位为XiX_i,对应的数字为aia_i,则这个X进制数转化为十进制数mm:

2022-11-24 (4).png

2

这题第一个点解决之后,就来到了第二个点,也就是如何求得最小值,我开始其实是想,如果两位相减出现负数,那么就是将位数变成最大值,如果不是负数,那么就取两位的最大值+1(因为要想出现XX,至少要是X+1X+1进制),但是这么搞了一遍发现,在洛谷上只过了2个点,得了20分,于是我就猜测不是这样,应该是不管怎么样都取X+1X+1进制,然后交了一发,得了80,我当时很开心,心想这应该就是贪心的策略(注:这个策略如果从严格的数学角度,我是不会证明的,我当时想着就是后面的即使短暂的变大,但是前面的正数依然会变化的更大,所以最优解依然是只选最小的),后来就是漫长的debug过程,不停的wa,我调试了,发现中间出现负数了,后来bcjjj帮我debug,发现是aibia_i-b_i可能是负数,需要在取模的过程中+mod再取模,最终耗时很久完成了,还是很开心的,收获不小。

代码

#include <string> 
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <stack> 
#include <cmath>
#include <algorithm>
#define int long long
using namespace std;
const int N=1000010;
const int mod=1000000007;
int a[N],c[N],b[N],x[N];
signed main(){
	int n,ma,mb,m;
	cin>>n;
	cin>>ma;
	for(int i=ma;i;i--) cin>>a[i];
	cin>>mb;
	for(int i=mb;i;i--) cin>>b[i];
	m=max(ma,mb);
    for(int i=1;i<=m;i++){
    	c[i]=a[i]-b[i];
	} 
	m=max(ma,mb);
	x[0]=1;
	for(int i=1;i<=m-1;i++){
		x[i]=max({2ll,a[i]+1,b[i]+1});
		x[i]=((x[i]%mod)*(x[i-1]%mod))%mod;
	}
	int ans=0;
	for(int i=m-1;i>=0;i--){
		ans=(ans+(c[i+1]%mod+mod)%mod*x[i]%mod)%mod;
	}
	cout<<ans<<endl;
	return 0;
}

希望能帮助到大家,QAQQAQ!