第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛) G 贪吃的派蒙

链接: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;
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值