【问题描述】
进制规定了数字在数位上逢几进一。
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的结果。
数据范围
对于 30% 的数据,N≤10;Ma,Mb≤8,
对于 100% 的数据,2≤N≤1000;1≤Ma,Mb≤100000;A≥B。
输入样例:
11
3
10 4 0
3
1 2 0
输出样例:
94
样例解释
当进制为:最低位 2 进制,第二数位 5 进制,第三数位 11 进制时,减法得到的差最小。
此时 A 在十进制下是 108,B 在十进制下是 14,差值是 94。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int mod = 1000000007;
int a[N],b[N],x[N];
int n,ma,mb;
int main()
{
cin>>n;
cin>>ma;
for(int i = 1;i <= ma;i++){
cin>>a[i];
}
cin>>mb;
for(int i = 1;i <= mb;i++){
cin>>b[i];
}
for(int i = 1;i <= ma / 2;i++){//将数据按低位到高位存放
swap(a[i],a[ma - i + 1]);
}
for(int i = 1;i <= mb / 2;i++){
swap(b[i],b[mb - i + 1]);
}
int k = max(ma,mb);//找出最大位数
for(int i = 1;i <= k;i++){
x[i] = max(2,max(a[i],b[i]) + 1);//x数组记录对应位置符合条件的最小的进制数
}
ll A = 0,B = 0;
for(int i = ma;i >= 1;i--){//注意从高位开始计算
A = (A * x[i] + a[i]) % mod;
}
for(int i = mb;i >= 1;i--){
B = (B * x[i] + b[i]) % mod;
}
ll ans = (A - B + mod) % mod; //加mod防止出现负数
printf("%lld",ans);
return 0;
}
总结:
1、X进制的理解
3 | 2 | 1 |
8 | 10 | 2 |
个位 1
十位 2 * 2
百位 3 * 10 * 2
规律:该位数字乘上前面所有进制数。
2、贪心算法
本题要找A - B的最小值,以为A >= B,所以只要找到满足条件的最小进制数(最小为二进制)即可。