CSUSTOJ-哈希的纸团(mid思维)
题目链接:http://acm.csust.edu.cn/problem/4054
CSDN食用链接:https://blog.csdn.net/qq_43906000/article/details/109520681
Description
哈希是一只喜欢叼纸的小猫,他每次都可以叼一团纸回家,纸的体积为\(1\),同时,他还可以把家中所有的纸团(可以只有一个纸团)合并成一个纸团,这个纸团的体积为\(所有纸团之和乘上p\),但是,哈希家中容量有限,最多只能存在\(k\)个纸团
现在哈希想让家中所有纸团的体积之和为\(n\),请你告诉他是否有可能.
input
一行三个整数\(n,p,k(1 \leq n ,k,p\leq 1e18)\)
output
如果可以,则输出"Just Do It",否则输出"No way".
Sample Input 1
10 4 3
Sample Output 1
Just Do It
Sample Input 2
11 4 3
Sample Output 2
No way
emmm,这题可能是我验题WA得最惨的一题了。。。思维要缜密
我们开始思考,第一回合拿\(k_1\)个纸团后乘上\(p\),第二个回合拿\(k_2\)个纸团后乘以\(p\)....
那么我们就可以得到一个表达式:\((....(((k_1p+k_2)p+k_3)p+k_4)p.......+k_n)=n\)
实际上化简出来就是\(k_1p^n+k_2p^{n-1}+...+k_n=n\)那么实际上就是用p进制来表示n,那么我们肯定要对\(p=1\)的情况处理掉,否则一旦n过于庞大就好T掉,那么我们就开始谨慎的讨论了:对于\(p=1\)的情况,如果k也为1,那么没什么好说的,n必须为1否则就直接GG,一旦k大于1,那么他就可以无限+1,一定会到达n。
接下来我们处理出p进制下的每一位的系数,我们知道第一次有k个位置给你放,也就是说如果\(p^n\)的系数大于k的话那就直接GG,融合之后一定会有一个纸团来占位,那么之后的所有的的系数都必须小于\(等于k-1\)
以下是AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mac=1e3+10;
ll a[mac];
ll qick(ll x,int b)
{
ll ans=1;
while (b){
if (b&1) ans*=x;
b>>=1;
x*=x;
}
return ans;
}
int main(int argc, char const *argv[])
{
ll n,p,k;
cin>>n>>p>>k;
if (p==1 && k!=1){
printf("Just Do It\n");
return 0;
}
if (p==1 && k==1) {
if (n>1) printf("No way\n");
else printf("Just Do It\n");
return 0;
}
if (n<=k) {printf("Just Do It\n"); return 0;}
ll nn=n,nb=0;
while (nn){
nn/=p;
nb++;
}
nb--;
for (int i=nb; i>=0; i--){
ll use=qick(p,i);
a[i]=n/use;
n-=a[i]*use;
}
int flag=0;
if (a[nb]>k) {printf("No way\n"); return 0;}
for (int i=nb-1; i>=0; i--)
if (a[i]>k-1) {flag=1; break;}
if (flag) printf("No way\n");
else printf("Just Do It\n");
return 0;
}