打卡信奥刷题(3351)用C++实现信奥题 P9560 [SDCPC 2023] Math Problem
·
P9560 [SDCPC 2023] Math Problem
题目描述
给定两个正整数 nnn 和 kkk,您可以进行以下两种操作任意次(包括零次):
- 选择一个整数 xxx 满足 0≤x<k0 \leq x < k0≤x<k,将 nnn 变为 k⋅n+xk\cdot n+xk⋅n+x。该操作每次花费 aaa 枚金币。每次选择的整数 xxx 可以不同。
- 将 nnn 变为 ⌊nk⌋\lfloor \frac{n}{k} \rfloor⌊kn⌋。该操作每次花费 bbb 枚金币。其中 ⌊nk⌋\lfloor \frac{n}{k} \rfloor⌊kn⌋ 表示小于等于 nk\frac{n}{k}kn 的最大整数。
给定正整数 mmm,求将 nnn 变为 mmm 的倍数最少需要花费几枚金币。请注意:000 是任何正整数的倍数。
输入格式
有多组测试数据。第一行输入一个整数 TTT(1≤T≤1051\leq T\leq 10^51≤T≤105)表示测试数据组数。对于每组测试数据:
第一行输入五个正整数 nnn,kkk,mmm,aaa,bbb(1≤n≤10181\leq n\leq 10^{18}1≤n≤1018,1≤k,m,a,b≤1091\leq k, m, a, b\leq 10^91≤k,m,a,b≤109)。
输出格式
每组数据输出一行一个整数,代表将 nnn 变为 mmm 的倍数最少需要花费几枚金币。如果无法完成该目标,输出 −1-1−1。
【样例解释】
对于第一组样例数据,一开始 n=101n=101n=101,最优操作如下:
- 首先进行一次第二种操作,将 nnn 变为 ⌊n4⌋=25\lfloor \frac{n}{4} \rfloor=25⌊4n⌋=25,花费 555 枚金币。
- 接下来进行一次第一种操作,选择 x=3x = 3x=3,将 nnn 变为 4⋅n+3=1034\cdot n+3=1034⋅n+3=103,花费 333 枚金币。
- 接下来进行一次第一种操作,选择 x=2x = 2x=2,将 nnn 变为 4⋅n+2=4144\cdot n+2=4144⋅n+2=414,花费 333 枚金币。
- 此时 414=2×207414=2 \times 207414=2×207,满足 nnn 是 mmm 的倍数。共花费 5+3+3=115+3+3=115+3+3=11 枚金币。
对于第二组样例数据,进行两次第二种操作将 nnn 变为 000。共花费 1+1=21 + 1 = 21+1=2 枚金币。
对于第三组样例数据,因为 n=114=6×19n = 114 = 6 \times 19n=114=6×19 已经是 mmm 的倍数,因此无需进行任何操作。共花费 000 枚金币。
输入输出样例 #1
输入 #1
4
101 4 207 3 5
8 3 16 100 1
114 514 19 19 810
1 1 3 1 1
输出 #1
11
2
0
-1
C++实现
#include<bits/stdc++.h>
using namespace std;
int t,k,m,a,b;
long long p[70],cnt,n;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--)
{
cin>>n>>k>>m>>a>>b;
cnt=1,p[1]=n;
while(k!=1&&n!=0)//p中记录所有操作二的可能结果
{
n/=k;
p[++cnt]=n;
}
long long ans=1e18;
for(int i=1;i<=cnt;i++)
{
if(k==1)//k=1要特判
{
if(p[i]%m==0)
ans=min(ans,1ll*(i-1)*b);
continue ;
}
int l=p[i],r=p[i];
long long sum=1ll*(i-1)*b;
while(l/m==r/m&&l%m!=0&&r%m!=0)
{
l*=k,r*=k;
r+=k-1;
sum+=a;
}
ans=min(ans,sum);
}
if(ans!=1e18)
cout<<ans<<"\n";
else
cout<<-1<<"\n";
}
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
更多推荐
所有评论(0)