ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

X 进制减法

2022-05-21 19:01:58  阅读:223  来源: 互联网

标签:数位 right 进制 减法 prod 十进制 left


X 进制减法

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

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

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

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

请你算出 $A−B$ 的结果最小可能是多少。

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

输入格式

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

第二行一个正整数 $M_{a}$,表示 $X$ 进制数 $A$ 的位数。

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

第四行一个正整数 $M_{b}$,表示 $X$ 进制数 $B$ 的位数。

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

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

输出格式

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

数据范围

对于 $30\%$ 的数据,$N \leq 10;M_{a},M_{b} \leq 8$,
对于 $100\%$ 的数据,$2 \leq N \leq 1000;1 \leq M_{a},M_{b} \leq 100000;A \geq B$。

输入样例:

11
3
10 4 0
3
1 2 0

输出样例:

94

样例解释

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

此时 $A$ 在十进制下是 ${10}^{8}$,$B$ 在十进制下是 $14$,差值是 $94$。

 

解题思路

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

  比如题目中的$X$进制下的$321$,是通过$3 \times 10 \times 2 + 2 \times 2 + 1 = 65$这样转换成十进制的。如果一个数一共有$n$位(最低位为第$0$位,最高位为第$n-1$位),第$i$位为数$a_{i}$,且第$i$位为$p_{i}$进制,那么将其转换成十进制就是$$\sum_{i=1}^{n-1} \left( {{a_{i} \cdot \prod_{j=0}^{i-1} {p_{j}}}} \right) + a_{0}$$

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

  假设$A = a_{n-1}a_{n-2} \dots a_{0}$,$B = b_{m-1}b_{m-2} \dots b_{0}$。

  首先因为每一位的进制是相同的,并且要求合法,因此会得到每一位的进制的取值范围为$max\{ 2,~ max\{ {a_{i} + 1,~ b_{i}+1 \}} \} \leq p_{i} \leq N$。

  把$A$转换成十进制,得到$$A = \sum_{i=1}^{n-1} \left( {{a_{i} \cdot \prod_{j=0}^{i-1} {p_{j}}}} \right) + a_{0} = a_{n-1}\prod_{i=0}^{n-2} {p_{i}} + a_{n-2}\prod_{i=0}^{n-3} {p_{i}} + \dots + a_{0}$$

  同理,把$B$转换成十进制,得到$$B = \sum_{i=1}^{m-1} \left( {{b_{i} \cdot \prod_{j=0}^{i-1} {p_{j}}}} \right) + b_{0} = b_{m-1}\prod_{i=0}^{m-2} {p_{i}} + b_{m-2}\prod_{i=0}^{m-3} {p_{i}} + \dots + b_{0}$$

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

  $A-B$得到的结果就是

\begin{align*}
A - B & = \sum_{i = 1}^{n-1} \left( {{ \left( {a_{i} - b_{i}} \right) \cdot \prod_{j = 0}^{i-1} {p_{j}}}} \right) + a_{0} - b_{0} \\
& = \left( a_{n-1} - b_{n-1} \right) \prod_{i = 0}^{n-2} {p_{i}} + \left( a_{n-2} - b_{n-2} \right) \prod_{i = 0}^{n-3} {p_{i}} + \dots + a_{0} - b_{0} \\
& = d_{n-1} \prod_{i = 0}^{n-2} {p_{i}} + d_{n-2} \prod_{i = 0}^{n-3} {p_{i}} + \dots + d_{0}
\end{align*}

其中$d_{i} = a_{i} - b_{i}$。虽然$A \geq B$,但$d_{i}$还是有可能小于$0$的。

  我们单独分析某个$p_{k}$,看看这个$p_{k}$取什么值,可以使得$A-B$最小。可以发现,对于每一项的$d_{i} \prod\limits_{j=0}^{i-1} {p_{j}}$,当$i$在$n-1 \sim k+1$这个范围内,每一项的$d_{i}$都会乘上$p_{k}$,当$i$在$k \sim 0$这个范围内,每一项的$d_{i}$都不会乘上$p_{k}$,因此在$A-B$中,我们把包含$p_{k}$的项提取出来,即$$d_{n-1} \prod_{i=0}^{n-2} {p_{i}} + d_{n-2} \prod_{i=0}^{n-3} {p_{i}} + \dots + d_{k+1} \prod_{i=0}^{k} {p_{i}}$$在把公因子$p_{k} \cdot p_{k-1} \cdots p_{0}$提取出来,得到$$\left( d_{n-1} \prod_{i=k+1}^{n-2} {p_{i}} + d_{n-2} \prod_{i=k+1}^{n-3} {p_{i}} + d_{k+1} \right) \cdot p_{k} \cdot p_{k-1} \cdots p_{0}$$

  首先可以发现$p_{k-1} \cdots p_{0}$是严格大于$0$的。

  然后我们下面证明$d_{n-1} \prod\limits_{i=k+1}^{n-2} {p_{i}} + d_{n-2} \prod\limits_{i=k+1}^{n-3} {p_{i}} + d_{k+1}$是严格大于等于$0$的。

  我们先把$d_{i}$换回$a_{i} - b_{i}$,得到$$\left( a_{n-1} - b_{n-1} \right) \prod_{i=k+1}^{n-2} {p_{i}} + \left( a_{n-2} - b_{n-2} \right) \prod_{i=k+1}^{n-3} {p_{i}} + a_{k+1} - b_{k+1}$$即$$a_{n-1} \prod_{i=k+1}^{n-2} {p_{i}} + a_{n-2} \prod_{i=k+1}^{n-3} {p_{i}} + a_{k+1} - \left( b_{n-1} \prod_{i=k+1}^{n-2} {p_{i}} + b_{n-2}\prod_{i=k+1}^{n-3} {p_{i}} + b_{k+1} \right)$$其中$a_{n-1} \prod\limits_{i=k+1}^{n-2} {p_{i}} + a_{n-2} \prod\limits_{i=k+1}^{n-3} {p_{i}} + a_{k+1}$为$A$的第$n-1 \sim k+1$位的前缀的十进制数,即$a_{n-1}a_{n-2} \dots a_{k+1}$对应的十进制数,同理$b_{n-1} \prod\limits_{i=k+1}^{n-2} {p_{i}} + b_{n-2}\prod\limits_{i=k+1}^{n-3} {p_{i}} + b_{k+1}$为$b_{n-1}b_{n-2} \dots b_{k+1}$对应的十进制数。

  又因为$A \geq B$,因此有$A$的前缀$\geq$$B$的前缀,即$$a_{n-1} \prod_{i=k+1}^{n-2} {p_{i}} + a_{n-2} \prod_{i=k+1}^{n-3} {p_{i}} + a_{k+1} \geq b_{n-1} \prod_{i=k+1}^{n-2} {p_{i}} + b_{n-2}\prod_{i=k+1}^{n-3} {p_{i}} + b_{k+1}$$即$$d_{n-1} \prod_{i=k+1}^{n-2} {p_{i}} + d_{n-2} \prod_{i=k+1}^{n-3} {p_{i}} + d_{k+1} \geq 0$$

  因此,要使$$\left( d_{n-1} \prod_{i=k+1}^{n-2} {p_{i}} + d_{n-2} \prod_{i=k+1}^{n-3} {p_{i}} + d_{k+1} \right) \cdot p_{k} \cdot p_{k-1} \cdots p_{0}$$最小,那么$p_{k}$应该尽可能取到最小,根据$p_{i}$的取值范围$max\{ 2,~ max\{ {a_{i} + 1,~ b_{i}+1 \}} \} \leq p_{i} \leq N$,因此对于每一个$p_{k}$,都应该取$p_{k} = max\{ 2,~ max\{ {a_{k} + 1,~ b_{k}+1 \}} \}$。

  其中求$A - B = d_{n-1} \prod\limits_{i=0}^{n-2} {p_{i}} + d_{n-2} \prod\limits_{i=0}^{n-3} {p_{i}} + \dots + d_{0}$可以用秦九韶算法。

  AC代码如下:

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10, mod = 1000000007;

int a[N], b[N];

int main() {
    int k, n, m;
    scanf("%d", &k);
    scanf("%d", &n);
    for (int i = n - 1; i >= 0; i--) {  // 读入A的每一位,倒叙存储即a0 a1 ... an-1
        scanf("%d", a + i);
    }
    scanf("%d", &m);
    for (int i = m - 1; i >= 0; i--) {  // 读入B的每一位,倒叙存储即b0 b1 ... bn-1
        scanf("%d", b + i);
    }
    
    int ret = 0;
    for (int i = max(n, m) - 1; i >= 0; i--) {
        // 每一位的进制数取max{2, a[i] + 1, b[i] + 1}
        ret = (1ll * ret * max(2, max(a[i], b[i]) + 1) + a[i] - b[i]) % mod;    // 秦九韶算法
    }
    
    printf("%d", ret);
    
    return 0;
}

 

参考资料

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

标签:数位,right,进制,减法,prod,十进制,left
来源: https://www.cnblogs.com/onlyblues/p/16295632.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有