X 进制减法

X 进制减法

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

X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!

例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则 X 进制数 321 转换为十进制数为 65

现在有两个 X 进制表示的整数 AB,但是其具体每一数位的进制还不确定,只知道 AB 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。

请你算出 AB 的结果最小可能是多少。

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

输入格式

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

第二行一个正整数 Ma,表示 X 进制数 A 的位数。

第三行 Ma 个用空格分开的整数,表示 X 进制数 A 按从高位到低位顺序各个数位上的数字在十进制下的表示。

第四行一个正整数 Mb,表示 X 进制数 B 的位数。

第五行 Mb 个用空格分开的整数,表示 X 进制数 B 按从高位到低位顺序各个数位上的数字在十进制下的表示。

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

输出格式

输出一行一个整数,表示 X 进制数 AB 的结果的最小可能值转换为十进制后再模 1000000007 的结果。

数据范围

对于 30% 的数据,N10;Ma,Mb8
对于 100% 的数据,2N1000;1Ma,Mb100000;AB

输入样例:

11
3
10 4 0
3
1 2 0

输出样例:

94

样例解释

当进制为:最低位 2 进制,第二数位 5 进制,第三数位 11 进制时,减法得到的差最小。

此时 A 在十进制下是 108B 在十进制下是 14,差值是 94

 

解题思路

  当时写这个题目的时候完全看不懂这个进制是怎么转换的,所以直接没写了。

  比如题目中的X进制下的321,是通过3×10×2+2×2+1=65这样转换成十进制的。如果一个数一共有n位(最低位为第0位,最高位为第n1位),第i位为数ai,且第i位为pi进制,那么将其转换成十进制就是i=1n1(aij=0i1pj)+a0

  现在给定两个数AB,要求这两个数每一位的进制数是相同的,且合法,要求每一位的进制数,使得AB的值最小。

  假设A=an1an2a0B=bm1bm2b0

  首先因为每一位的进制是相同的,并且要求合法,因此会得到每一位的进制的取值范围为max{2, max{ai+1, bi+1}}piN

  把A转换成十进制,得到A=i=1n1(aij=0i1pj)+a0=an1i=0n2pi+an2i=0n3pi++a0

  同理,把B转换成十进制,得到B=i=1m1(bij=0i1pj)+b0=bm1i=0m2pi+bm2i=0m3pi++b0

   为了方便,如果nm,我们就在位数少的数前面补0。比如如果这里的m<n,那么我们在B的最高位开始补nm0,这并不影响转换成十进制的结果。因此下面的分析把m改成n,其中bn1bm都为0

  AB得到的结果就是

AB=i=1n1((aibi)j=0i1pj)+a0b0=(an1bn1)i=0n2pi+(an2bn2)i=0n3pi++a0b0=dn1i=0n2pi+dn2i=0n3pi++d0

其中di=aibi。虽然AB,但di还是有可能小于0的。

  我们单独分析某个pk,看看这个pk取什么值,可以使得AB最小。可以发现,对于每一项的dij=0i1pj,当in1k+1这个范围内,每一项的di都会乘上pk,当ik0这个范围内,每一项的di都不会乘上pk,因此在AB中,我们把包含pk的项提取出来,即dn1i=0n2pi+dn2i=0n3pi++dk+1i=0kpi在把公因子pkpk1p0提取出来,得到(dn1i=k+1n2pi+dn2i=k+1n3pi+dk+1)pkpk1p0

  首先可以发现pk1p0是严格大于0的。

  然后我们下面证明dn1i=k+1n2pi+dn2i=k+1n3pi+dk+1是严格大于等于0的。

  我们先把di换回aibi,得到(an1bn1)i=k+1n2pi+(an2bn2)i=k+1n3pi+ak+1bk+1an1i=k+1n2pi+an2i=k+1n3pi+ak+1(bn1i=k+1n2pi+bn2i=k+1n3pi+bk+1)其中an1i=k+1n2pi+an2i=k+1n3pi+ak+1A的第n1k+1位的前缀的十进制数,即an1an2ak+1对应的十进制数,同理bn1i=k+1n2pi+bn2i=k+1n3pi+bk+1bn1bn2bk+1对应的十进制数。

  又因为AB,因此有A的前缀B的前缀,即an1i=k+1n2pi+an2i=k+1n3pi+ak+1bn1i=k+1n2pi+bn2i=k+1n3pi+bk+1dn1i=k+1n2pi+dn2i=k+1n3pi+dk+10

  因此,要使(dn1i=k+1n2pi+dn2i=k+1n3pi+dk+1)pkpk1p0最小,那么pk应该尽可能取到最小,又因为每一个位的pk的取值是相互独立的,根据pi的取值范围max{2, max{ai+1, bi+1}}piN,因此对于每一个pk,都应该取pk=max{2, max{ak+1, bk+1}}

  其中求AB=dn1i=0n2pi+dn2i=0n3pi++d0可以用秦九韶算法。

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5 + 10, mod = 1000000007;
 5 
 6 int a[N], b[N];
 7 
 8 int main() {
 9     int k, n, m;
10     scanf("%d", &k);
11     scanf("%d", &n);
12     for (int i = n - 1; i >= 0; i--) {  // 读入A的每一位,倒叙存储即a0 a1 ... an-1
13         scanf("%d", a + i);
14     }
15     scanf("%d", &m);
16     for (int i = m - 1; i >= 0; i--) {  // 读入B的每一位,倒叙存储即b0 b1 ... bn-1
17         scanf("%d", b + i);
18     }
19     
20     int ret = 0;
21     for (int i = max(n, m) - 1; i >= 0; i--) {
22         // 每一位的进制数取max{2, a[i] + 1, b[i] + 1}
23         ret = (1ll * ret * max(2, max(a[i], b[i]) + 1) + a[i] - b[i]) % mod;    // 秦九韶算法
24     }
25     
26     printf("%d", ret);
27     
28     return 0;
29 }
复制代码

 

参考资料

  AcWing 4404. X 进制减法(蓝桥杯C++ AB组辅导课):https://www.acwing.com/video/3801/

posted @   onlyblues  阅读(785)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示