【2024.2.3练习】X 进制减法

题目描述

【2024.2.3练习】X 进制减法_第1张图片

【2024.2.3练习】X 进制减法_第2张图片


题目分析

这是一道阅读题。先分析第一段给出的范例:X进制数x(321),由于个位数逢2进1,十位数逢10进1,故x(321) = 3\times 10\times 2+2\times 2+1 = 65,这样便得到了X进制转十进制数字的算法。

再来看输入格式。第一行限定了X进制的X最大值,第二到五行输入了同一进制规则的两个X进制数AB,要求输出A-B的最小可能结果。

根据数据范围,先排除暴力枚举的可能性。不妨先求出A-B的X进制表示结果,即每一位数对应相减。再分析如何设计X进制可以让结果最小。

由于数据实在太大了,考虑该题是否满足贪心。首先想每位数的进制是否都要取到最小。分类讨论:若AB每一位数对应相减均为正数,显然每位数进制都要取最小;当存在某一位数对应相减为负数,由于题干说明A\geq B,最大位上一定不为负数,若某一位出现负数则+N,并向下一位借1,这样不会影响A-B的值,但最终会将所有位数变成正数,第二种情况就归纳进了第一种情况。综上贪心成立。


我的代码

注意细节,输入是从高位到低位,结果可能很大要取模,用Longlong存储数据。

#include 
#include 
using namespace std;
const int max_n = 1e5+1;
typedef long long ll;
ll A[max_n];
ll B[max_n];
ll N[max_n];
ll min_n = 2;
int main() {
	int n;
	int a;
	int b;
	cin >> n;
	cin >> a;
	for (int i = a; i >= 1; i--)
	{
		cin >> A[i];
	}
	cin >> b;
	for (int i = a; i >= 1; i--)
	{
		if (i <= b) {
			cin >> B[i];
		}
		else
		{
			B[i] = 0;
		}
		N[i] = max(min_n, max(A[i] + 1, B[i] + 1));
	}
	//计算结果
	ll ans = 0;
	ll muti = 1;
	for (int i = 1; i <= a; i++)
	{
		ans = ans + (A[i] - B[i]) * muti;
		ans = ans % 1000000007;
		muti = muti * N[i];
		muti = muti % 1000000007;
	}
	cout << ans;
	return 0;
}

你可能感兴趣的:(练习日志,算法,c++,学习)