码迷,mamicode.com
首页 > 其他好文 > 详细

题解【Luogu6022 快乐水】

时间:2020-01-30 23:10:28      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:tle   rip   efi   信息   register   ||   情况下   puts   return   

\[ Preface \]

大概在半年前出过这道(((

然后当天读完这题,把自己写的 std 改了一下 ll 和特判信息交上去就 A 了。

捡了个大便宜。
\[ Description \]
你一开始有 \(n\) 瓶快乐水。

\(m\) 个附属品,每喝一瓶快乐水就可以得到这 \(m\) 个附属品各 \(1\) 个,若有 \(a[i]\) 个附属品 \(i\) ,就可以再换一瓶快乐水。

问一共可以喝多少瓶快乐水。若可以无限白嫖就输出 Inf
\[ Solution \]
一瓶一瓶处理快乐水显然是会 TLE 的,所以我们要批量处理快乐水。

\(~\)

我们开个桶 cnt[x] 表示 " 附属品 \(x\) 的数量 " 。

每次我们批量处理当前的 \(n\) 瓶快乐水:

  1. ans += n ,表示喝掉了当前的 \(n\) 瓶快乐水。
  2. cnt[i] += n ,表示得到了这 \(m\) 个附属品各 \(n\) 个。
  3. n += cnt[i] / a[i], cnt[i] %= a[i] ,表示用把能换的快乐水都换了。

直到 \(n=0\) ,此时 \(ans\) 就是所求。

\(~\)

当然,还有无限白嫖快乐水的情况,在该情况下,\(n\) 永远不会等于 \(0\) ,也就是说快乐水会越喝越多了。

稍加分析一下我们发现:若不能无限白嫖,在任意时刻快乐水的数量不会大于等于初始给出的 \(n\)

想想看,如果可以无限白嫖,就相当于说,你用 \(n\) 瓶快乐水经过若干轮变换,换到了 \(k\) \((n \leq k)\) 瓶快乐水,那你再在这 \(k\) 瓶快乐水中选出 \(n\) 瓶快乐水再进行若干轮变换,又可以得到 \(k\) 瓶快乐水,如此往复,你总是可以白嫖快乐水。

于是就可以用上述性质判断是否无限白嫖快乐水了。
\[ Code \]

#include<cstdio>

#define RI register int

using namespace std;

inline int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}

const int N=100100,M=10;

int n,m,lim;

int a[N],cnt[M];

long long ans;

int main()
{
    n=read(),m=read();

    lim=n;

    for(RI i=1;i<=m;i++)
        a[i]=read();

    while(n)
    {
        ans+=n;

        for(RI i=1;i<=m;i++)
            cnt[i]+=n;

        n=0;

        for(RI i=1;i<=m;i++)
            n+=cnt[i]/a[i],cnt[i]%=a[i];

        if(n>=lim)
        {
            puts("Inf");
            return 0;
        }
    }

    printf("%lld\n",ans);

    return 0;
}

\[ Thanks \ for \ watching \]

题解【Luogu6022 快乐水】

标签:tle   rip   efi   信息   register   ||   情况下   puts   return   

原文地址:https://www.cnblogs.com/cjtcalc/p/12244206.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!