链接:https://ac.nowcoder.com/acm/contest/11746/G
来源:牛客网
题目描述
在遥远的提瓦特大陆上,正在筹备一年一度的羽球节,猎鹿人餐厅为犒劳认真筹备的众人,准备了K份甜甜花酿鸡供大家排队领取。
在每一次的排队中,编号为i的角色领取上限为Ai,这意味着他可以领取的甜甜花酿鸡在[1-Ai]范围内。当一个角色领完本次的甜甜花酿鸡,他/她就会回到队列的末尾,直到所有甜甜花酿鸡都被吃完为止。当轮到一个角色领取时,如果所有的甜甜花酿鸡都被领完,那么他/她就要帮大家刷盘子。
贪吃的派蒙每次都吃固定的Ax个甜甜花酿鸡(如果剩下的甜甜花酿鸡的数量比Ax小,那么他就把剩下的都吃完)。我们很容易找到派蒙的编号,Ax比其他所有的Ai都要大。大家都想让派蒙最后留下来刷盘子,请你写一个程序来判断这是否可能。
输入描述:
第一行包含一个整数T(1≤T≤100),表示有T组测试数据。
接下来每组测试数据包含两行。
第一行包含两个整数N和K(2≤N≤105,0≤K≤108),分别表示人数和甜甜花酿鸡的数量。
第二行包含一个整数Ai(1≤Ai≤10^9),表示队列中编号为i的角色可以领取甜甜花酿鸡的最大数量。始终只有一个最大的Ax。
输出描述:
如果大家能找到一种方案让派蒙刷盘子,那么输出“YES”。否则输出“NO”。
示例1
输入
复制
1
4 3
1 2 3 2
输出
复制
YES
示例2
输入
复制
1
5 8
1 2 3 2 1
输出
复制
NO
思路:
类似于博弈吧。
很明显这个循环的次数越多对派蒙就越不利。
设派蒙所在位置k;
会发现要让派蒙洗碗的最小食物数是k;
用总食物数-k得到可用食物数。
然后想办法消耗掉可用食物数。
然后发现循环的次数越多可消耗的食物数就越多。
然后根据这个性质模拟求解。
还有个细节 就是 可能会爆longlong 所以用了Int128;
具体实现见代码:
emmmm 不用int128也行。。。。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+15;
typedef __int128 ll;
inline __int128 read()
{
__int128 x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
ll a[N];
int main()
{
ll t;
t=read();
while(t--)
{
ll n,ss;
__int128_t maxn,sum,k,s;
k=maxn=sum=0;
n=read();
ss=read();
s=ss;
for(int i=1;i<=n;i++)
{
a[i]=read();
if(a[i]>maxn)
{
maxn=a[i];
k=i;
}
sum+=a[i];
}
if(s<k)
{
cout<<"NO"<<endl;
continue;
}
s-=k;
ll op=maxn+n-1;
ll od=s/op; ///能几趟
ll oq=s%op; ///剩下的
ll yu=od*(sum-op);
for(int i=1;i<=k;i++)
{
yu+=(a[i]-1);
}
if(yu>=oq)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}