题目链接:
题目描述:
进制规定了数字在数位上逢几进一。
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。
题目分析:
这道题主要难在看懂题目,一旦看懂题目了之后就好做了。
- 题目中的样例计算过程为: 321 ==》 65
- 3 * 10 * 2 + 2 * 2 + 1 * 1 == 65 (其实就是当前这一位是又后面的每一位的进制乘的,而不是由自己的进制乘的)
算法1:
贪心 – 时间复杂度O(n):
由于题目已经给定 A >= B 的,那么这题就好做了,因为每一位进制都会 乘到 A 和 B里面,当 k 越大的时候 A 和 B都会越大,但是因为 A >= B 的,所以 A 的增长速率是始终大于 B 的, 所以 k 越大,A - B 的差值就越大,所以我们只要每次取 k 最小,就能满足 A - B 的差值最小了,又因为每一位的值都是由前面每一位的进制乘起来的,所以我们可以开一个 pre 变量,来记录前面所有进制的乘积
代码:
/*
* @Author: suhuamo
* @Date: 2022-04-12 11:07:51
* @LastEditTime: 2022-04-13 15:23:23
* @FilePath: \algorithm\蓝桥杯\第十三届蓝桥杯省赛B\E.cpp
* @slogan: 也许散落在浩瀚宇宙的小行星们也知道
* 知识点: 简单模拟
* 由于答案确保了 A >= B,那么由于A的位数是一定多余B的位数的,那么只要任何一个位数取大了,都是A会远远大于B
* 所以每一个位数取最小才能保证差最小
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1000000007;
int K, Ma, Mb;
int a[N], b[N];
int main()
{
cin >> K >> 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];
// pre 就是 保存前面所有进制的乘积
LL res = 0, pre = 1;
for(int i = 0; i < Mb; i++)
{
int k = max(2, max(a[i] + 1, b[i] + 1));
res = (res + pre * (a[i] - b[i]) % mod) % mod;
pre = pre * k % mod;
}
// 因为 A >= B, 所以 A 的位数肯定大于等于 B 的位数
for(int i = Mb; i < Ma; i++)
{
int k = max(2, a[i] + 1);
res = (res + pre * a[i] % mod) % mod;
pre = pre *k % mod;
}
cout << (res % mod + mod) % mod << endl;
return 0;
}