第一题,2.5在数组初始化时强制转为整数
第二题,传入的两个类型要相同
题目描述
进制规定了数字在数位上逢几进一。
X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!
例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则 X 进制数 321 转换为十进制数为 65。
现在有两个 X 进制表示的整数 A 和 B,但是其具体每一数位的进制还不确定,只知道 A 和 B 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。
请你算出 A−B 的结果最小可能是多少。
请注意,你需要保证 A 和 B 在 X 进制下都是合法的,即每一数位上的数字要小于其进制。
输入格式
第一行一个正整数 N,含义如题面所述。
第二行一个正整数 Ma,表示 X 进制数 A 的位数。
第三行 Ma 个用空格分开的整数,表示 X 进制数 A 按从高位到低位顺序各个数位上的数字在十进制下的表示。
第四行一个正整数 Mb,表示 X 进制数 B 的位数。
第五行 Mb 个用空格分开的整数,表示 X 进制数 B 按从高位到低位顺序各个数位上的数字在十进制下的表示。
请注意,输入中的所有数字都是十进制的。
输出格式
输出一行一个整数,表示 X 进制数 A−B 的结果的最小可能值转换为十进制后再模 1000000007 的结果。
数据范围
对于 30% 的数据,N≤10;Ma,Mb≤8,
对于 100% 的数据,2≤N≤1000;1≤Ma,Mb≤100000;A≥B。
输入样例:
11
3
10 4 0
3
1 2 0
输出样例:
94
样例解释
当进制为:最低位 2 进制,第二数位 5 进制,第三数位 11 进制时,减法得到的差最小。
此时 A 在十进制下是 108,B 在十进制下是 14,差值是 94。
思路
推出进制计算方式:每一位数字,乘以该数字数位后所有进制数,求和即为结果
欲使A-B最小,只需使得各位数字取得合法范围内的最小进制即可,具体做法就是对A和B中相同数位的数字取xmax = max(a[i], b[i]),该位的合法最小进制即为max(xmax + 1, 2)
因为最小进制不能小于2;而对于X进制的数来说,合法的最大数字是X-1,例如8进制中最大数字是7,二进制中最大数字是1。
而求A和B的值,只需要再开一个数组存储各位数字的实际权重,再将各位数字和对应的权重相乘后相加即可。
需要注意的是这个题数据比较大,需要多次取模,特别是最后计算最终结果的时候,应(A - B + mod) % mod,否则可能A本来比B大,但是取模后比B小,这样A-B可能会出现负值。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10,mod=1000000007;
ll a[N],b[N],w[N],mul[N];
ll A,B;
//a存储A各位数字,b存储B各位数字,w存储各位的进制,mul存储各位数字的实际权重
int main(){
int n,ma,mb;
cin>>n; // 最大进制
cin>>ma;
for(int i=ma;i>=1;i--) cin>>a[i];
cin>>mb;
for(int i=mb;i>=1;i--) cin>>b[i];
// 确定各位进制 w[i]
int maxx=max(ma,mb); // A B 中最大的位数
for(int i=maxx;i>=1;i--){
int tmax=max(a[i],b[i]);
w[i]=max(2,tmax + 1);
}
// 计算权重
mul[1]=1;
for(int i=2;i<=maxx;i++){
mul[i]=w[i-1]*mul[i-1]%mod;
}
// 计算A
for(int i=ma;i>=1;i--){
A=(A+a[i]*mul[i])%mod;
}
// 计算B
for(int i=mb;i>=1;i--){
B=(B+b[i]*mul[i])%mod;
}
// A - B
cout<<(A-B+mod)%mod<<endl;
return 0;
}
double ans = ...; // 之前计算出的结果
int res = static_cast<int>(ans); // static_cast 用于进行静态类型转换,一般不会执行运行时类型检查
if (ans < res) // 如果计算结果小数位上的数字不为 0,那么需要下取整
res--; // 直接将小数部分直接去掉,即下取整
return res; // 返回下取整后的结果
template <typename A, typename B>
decltype(A{} + B{}) demo2(A a, B b)
{
// static_cast 用于进行静态类型转换,一般不会执行运行时类型检查
return static_cast<decltype(A{} + B{})> (a + b);
}