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,pleq 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
");
		return 0;
	}
	if (p==1 && k==1) {
		if (n>1) printf("No way
");
		else printf("Just Do It
");
		return 0;
	}
	if (n<=k) {printf("Just Do It
"); 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
"); return 0;}
	for (int i=nb-1; i>=0; i--)
		if (a[i]>k-1) {flag=1; break;}
	if (flag) printf("No way
");
	else printf("Just Do It
");
	return 0;
}
原文地址:https://www.cnblogs.com/lonely-wind-/p/13941884.html