洛谷P6022 快乐水

无聊来写一写题解吧

比赛的水题:模拟
但是第十个数据是真的毒瘤

题目传送门

sol

思路很简单,一开始小A有n瓶快乐水,商店有m个附属品(也就是有m种白嫖快乐水的方式),就枚举呗。

枚举每一个附属品,未喝的加上它的权值整除初值,并用它的权值对初值取模。

判断边界,其实也很简单,当每一个附属品的权值都小于初值,就可以退出了
如果没有,就输出“Inf”,即可以无限白嫖快乐水

code

#include<cstdio>
#define ull unsigned long long//防止爆,开了ull,开long long一样
using namespace std;
inline int read(){
	int res=0,sign=1;char ch;
	while((ch=getchar())<'0'||ch>'9')if(ch=='-')sign=-1;res=res*10+ch-48;
	while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;
	return res*sign;
}//快读不解释
const int maxn=6;
int n,m;
ull f[maxn];//初值
ull num[maxn];//累计每一个附属品权值
long long bu=0;//计算步数
ull ans=0,weihe=0;//ans记录最多能喝的快乐水,weihe没喝的快乐水
bool flag=true;//判断边界,是否可以无限白嫖
int main(){
	n=read(),m=read();
	for(int i=1;i<=m;i++)f[i]=read();//读入
	weihe=n;
	ans+=weihe;//已喝n瓶
	for(ull i=1;i<=m;i++)
	 num[i]+=weihe;//累计加上
	weihe=0;
	while(true){
		bu++;
		flag=true;
		for(ull i=1;i<=m;i++)
		 num[i]+=weihe;
		ans+=weihe;//每一步都要加上没喝的快乐水
		weihe=0;
		for(ull i=1;i<=m;i++){
			if(num[i]>=f[i]){
		 	  flag=false;
		 	  break;
		    }
		    if(num[i]<f[i])continue;
		}//判断边界,如果每一个附属品权值都小于初值,即退出
		if(flag)break;
	    for(int i=1;i<=m;i++){
	    	weihe+=num[i]/f[i];
	    	num[i]=num[i]%f[i];
		}//未喝的加上它的权值整除初值,并用它的权值对初值取模
		if(bu==50000000){puts("Inf");return 0;}//如果步数很大,就可以无限白嫖
	} 
	printf("%llu",ans);//输出最多能喝的快乐水
	return 0;
}

完结撒花

猜你喜欢

转载自www.cnblogs.com/qzwer/p/13168184.html