本文涉及知识点
P8782[蓝桥杯 2022 省 B] X 进制减法
题目描述
进制规定了数字在数位上逢几进一。
X
X
X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!例如说某种
X
X
X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则
X
X
X 进制数 321
转换为十进制数为 65
。
现在有两个 X X X 进制表示的整数 A A A 和 B B B,但是其具体每一数位的进制还不确定,只知道 A A A 和 B B B 是同一进制规则,且每一数位最高为 N N N 进制,最低为二进制。请你算出 A − B A-B A−B 的结果最小可能是多少。
请注意,你需要保证 A A A 和 B B B 在 X X X 进制下都是合法的, 即每一数位上的数字要小于其进制。
输入格式
第一行一个正整数 N N N,含义如题面所述。
第二行一个正整数 M a M_{a} Ma,表示 X X X 进制数 A A A 的位数。
第三行 M a M_{a} Ma 个用空格分开的整数,表示 X X X 进制数 A A A 按从高位到低位顺序各个数位上的数字在十进制下的表示。
第四行一个正整数 M b M_{b} Mb,表示 X X X 进制数 B B B 的位数。
第五行 M b M_{b} Mb 个用空格分开的整数,表示 X X X 进制数 B B B 按从高位到低位顺序各个数位上的数字在十进制下的表示。
请注意,输入中的所有数字都是十进制的。
输出格式
输出一行一个整数,表示 X X X 进制数 A − B A-B A−B 的结果的最小可能值转换为十进制后再模 1000000007 1000000007 1000000007(即 1 0 9 + 7 10^9+7 109+7)的结果。
样例 #1
样例输入 #1
11
3
10 4 0
3
1 2 0
样例输出 #1
94
提示
【样例说明】
当进制为:最低位 2 2 2 进制, 第二数位 5 5 5 进制, 第三数位 11 11 11 进制时, 减法得到的差最小。此时 A A A 在十进制下是 108 108 108, B B B 在十进制下是 14 14 14,差值是 94 94 94。
【评测用例规模与约定】
对于 30 % 30 \% 30% 的数据, N ≤ 10 , M a , M b ≤ 8 N \leq 10,M_{a}, M_{b} \leq 8 N≤10,Ma,Mb≤8.
对于 100 % 100 \% 100% 的数据, 2 ≤ N ≤ 1000 , 1 ≤ M a , M b ≤ 1 0 5 , A ≥ B 2 \leq N \leq 1000,1 \leq M_{a}, M_{b} \leq 10^5,A \geq B 2≤N≤1000,1≤Ma,Mb≤105,A≥B。
蓝桥杯 2022 省赛 B 组 E 题。
贪心
补齐后,让位数相等。如果A
≥
\geq
≥B,则各位的进制都是越小越好。从低位到高为枚举各位的最大值m,则此位是max(2,m+1)进制。
ans += 比i低的位的m之积 * (a[i]-b[i])
如果A < B,则各位的进制越大越好。本题A
≥
\geq
≥B
注意:A的长度,可能小于B。即B有前导0。
代码
核心代码
#include <iostream>
#include <sstream>
#include <vector>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<string>
#include<algorithm>
#include<functional>
#include<queue>
#include <stack>
#include<iomanip>
#include<numeric>
#include <math.h>
#include <bitset>
using namespace std;
template<int MOD = 1000000007>
class C1097Int
{
public:
C1097Int(long long llData = 0) :m_iData(llData% MOD)
{
}
C1097Int operator+(const C1097Int& o)const
{
return C1097Int(((long long)m_iData + o.m_iData) % MOD);
}
C1097Int& operator+=(const C1097Int& o)
{
m_iData = ((long long)m_iData + o.m_iData) % MOD;
return *this;
}
C1097Int& operator-=(const C1097Int& o)
{
m_iData = (m_iData + MOD - o.m_iData) % MOD;
return *this;
}
C1097Int operator-(const C1097Int& o)
{
return C1097Int((m_iData + MOD - o.m_iData) % MOD);
}
C1097Int operator*(const C1097Int& o)const
{
return((long long)m_iData * o.m_iData) % MOD;
}
C1097Int& operator*=(const C1097Int& o)
{
m_iData = ((long long)m_iData * o.m_iData) % MOD;
return *this;
}
C1097Int operator/(const C1097Int& o)const
{
return *this * o.PowNegative1();
}
C1097Int& operator/=(const C1097Int& o)
{
*this /= o.PowNegative1();
return *this;
}
bool operator==(const C1097Int& o)const
{
return m_iData == o.m_iData;
}
bool operator<(const C1097Int& o)const
{
return m_iData < o.m_iData;
}
C1097Int pow(long long n)const
{
C1097Int iRet = 1, iCur = *this;
while (n)
{
if (n & 1)
{
iRet *= iCur;
}
iCur *= iCur;
n >>= 1;
}
return iRet;
}
C1097Int PowNegative1()const
{
return pow(MOD - 2);
}
int ToInt()const
{
return (m_iData+ MOD)%MOD;
}
private:
int m_iData = 0;;
};
class Solution {
public:
int MinS(int n, vector<int>& A, vector<int>& B) {
if (A.size() < B.size()) {
vector<int> tmp(B.size() - A.size());
tmp.insert(tmp.end(), A.begin(), A.end());
tmp.swap(A);
}
if (B.size() < A.size()) {
vector<int> tmp(A.size() - B.size());
tmp.insert(tmp.end(), B.begin(), B.end());
tmp.swap(B);
}
const int N = A.size();
C1097Int<> ans;
C1097Int<> unit(1);
for (int i = N - 1; i >= 0; i--) {
ans += unit * (A[i] - B[i]);
int cur = max(A[i], B[i]) + 1;
unit *= max(cur, 2);
}
return ans.ToInt();
}
};
int main() {
#ifdef _DEBUG
freopen("a.in", "r", stdin);
#endif // DEBUG
int n;
scanf("%d", &n);
int ma, mb;
scanf("%d", &ma);
vector<int> A;
for (int i = 0; i < ma; i++) {
int d;
scanf("%d", &d);
A.emplace_back(d);
}
scanf("%d", &mb);
vector<int> B(0);
for (int i = 0; i < mb; i++) {
int d;
scanf("%d", &d);
B.emplace_back(d);
}
Solution slu;
auto res = slu.MinS(n, A, B);
printf("%d\r\n", res);
return 0;
}
单元测试
TEST_METHOD(TestMethod11)
{
int n = 11;
vector<int> A = { 10, 4 ,0 };
vector<int> B = { 1,2 ,0 };
auto res = Solution().MinS(n, A, B);
AssertEx(94, res);
}
TEST_METHOD(TestMethod12)
{
int n = 11;
vector<int> A = {0, 10, 4 ,0 };
vector<int> B = { 1,2 ,0 };
auto res = Solution().MinS(n, A, B);
AssertEx(94, res);
}
TEST_METHOD(TestMethod13)
{
int n = 11;
vector<int> A = { 10, 4 ,0 };
vector<int> B = { 0, 1,2 ,0 };
auto res = Solution().MinS(n, A, B);
AssertEx(94, res);
}
扩展阅读
我想对大家说的话 |
---|
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。 |
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作 |
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 |
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
如果程序是一条龙,那算法就是他的是睛 |
失败+反思=成功 成功+反思=成功 |
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。