进制规定了数字在数位上逢几进一。
X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!例如说某
种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则X 进制数 321 转换为
十进制数为 65。
现在有两个 X 进制表示的整数 A 和 B,但是其具体每一数位的进制还不确
定,只知道 A 和 B 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。
请你算出 A B 的结果最小可能是多少。
请注意,你需要保证 A 和 B 在 X 进制下都是合法的,即每一数位上的数字要小于其进制。
【输入格式】
第一行一个正整数 N,含义如题面所述。
第二行一个正整数 Ma,表示 X 进制数 A 的位数。
第三行 Ma 个用空格分开的整数,表示 X 进制数 A 按从高位到低位顺序各
个数位上的数字在十进制下的表示。
第四行一个正整数 Mb,表示 X 进制数 B 的位数。
第五行 Mb 个用空格分开的整数,表示 X 进制数 B 按从高位到低位顺序各
个数位上的数字在十进制下的表示。
请注意,输入中的所有数字都是十进制的。
【输出格式】
输出一行一个整数,表示 X 进制数 A B 的结果的最小可能值转换为十进
制后再模 1000000007 的结果。
【样例输入】
11
3
10 4 0
3
1 2 0
【样例输出】
94
【样例说明】
当进制为:最低位 2 进制,第二数位 5 进制,第三数位 11 进制时,减法
得到的差最小。此时 A 在十进制下是 108,B 在十进制下是 14,差值是 94。
【评测用例规模与约定】
对于 30% 的数据,N ≤ 10; Ma, Mb ≤ 8.
对于 100% 的数据,2 ≤ N ≤ 1000; 1 ≤ Ma, Mb ≤ 100000; A ≥ B.
本题最为难以理解的一步就是题目中的进制减法是怎个说法,以及题目中的321转为十进制后是65,它是怎么来的。当理解了这个之后,这道题基本上也就迎刃而解了
321是怎样转为十进制的65的:
首先,先用熟悉的十进制数来理解这个问题,
比如,十进制下的9 让9+1 成为10,是如何来的。
个位数是十进制,在个位上思考,9+1,就是10,并且因为是十进制,所以进一位,本位(即个位)为0,最终就是10(十位数为1,个位数为0)
那么将它带入本题:321,第一位是二进制,第二位是十进制,第三位是八进制,从0开始,则是0 1 2(因为第一位是二进制,所以逢二加一)->10 11 20(因为第二位是十进制,所以逢十加一,此时为2,无需进一) ······ 91 92(因为第一位是二进制,所以进一,个位为0,第二位9+1,因为第二位是十进制,则也需进一)->100 ···
理解之后,321如何转化为65,也就很好得出了,1(第一位数)+2(第二位数)*2(二进制)+3(第三位数)*2(二进制)*10(十进制) = 1+4+60 = 65
接下来的就很好理解了,下面的将以题目给的样例为例子
两数相减的最小数,先将两个数相减,随后再确定每位的进制 A:10 4 0 B:1 2 0
对应位数A-B,则结果为 C:9 2 0
我们此时需要的仅为,让C的结果最小,如何让C的结果最小,C的每一位数已经确定,无法更改,那么我们只有在进制方面最小,则结果就为最小。并且注意A和B均要合法,所以每一位的进制,就是此位上两个数的最大值+1 A和B:第三位数的最大值为10,则为11进制,第二位数最大值为4,则为5进制,第一位数的最大值为0,则为2进制
当C中的某一位数为负数时,此推论也成立,(可以想象,比如 7 -1,要想第一位的数大于0,则需要第二位减一,第一位加上第一位的进制数,我们需要它最小,那么就是进制最小的情况)
下面则是我写的代码
#include <bits/stdc++.h>
using namespace std;
const int mod = 1000000007;
int N;
int Ma,Mb;
int a[100000],b[100000];
long long jinzhi[1000000];//若此处不为long long 类型,则只能获得30分,此处的进制,不是本位的进制,是前缀和
int main(){
cin>>N;
cin>>Ma;
for(int i=Ma-1;i>=0;i--){
cin>>a[i];
}
cin>>Mb;
for(int i=Mb-1;i>=0;i--){
cin>>b[i];
}
int n = max(Ma,Mb);
jinzhi[0] = 1;
for(int i=0;i<n;i++){
int maxn = max(a[i],b[i]);
if(maxn==0){
jinzhi[i] = 2;
}else{
jinzhi[i] = maxn+1;
}
if(i>0)
jinzhi[i] = (jinzhi[i]*jinzhi[i-1])%mod;
}
long long ans = a[0]-b[0];
for(int i=1;i<n;i++){
ans= (ans+ ((a[i]-b[i])*jinzhi[i-1]))%mod;//当前位乘前一位的进制
}
ans %= mod;
cout<<ans<<endl;
return 0;
}