【C++贪心】P8782[蓝桥杯 2022 省 B] X 进制减法|普及

本文涉及知识点

C++贪心

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 AB 的结果最小可能是多少。

请注意,你需要保证 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 AB 的结果的最小可能值转换为十进制后再模 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 N10,Ma,Mb8.

对于 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 2N1000,1Ma,Mb105,AB

蓝桥杯 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++**实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软件架构师何志丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值