題解【Luogu6022 快樂水】

\[ Preface \]spa

大概在半年前出過這道(((code

而後當天讀完這題,把本身寫的 std 改了一下 ll 和特判信息交上去就 A 了。ip

撿了個大便宜。
\[ Description \]
你一開始有 \(n\) 瓶快樂水。get

\(m\) 個附屬品,每喝一瓶快樂水就能夠獲得這 \(m\) 個附屬品各 \(1\) 個,如有 \(a[i]\) 個附屬品 \(i\) ,就能夠再換一瓶快樂水。io

問一共能夠喝多少瓶快樂水。若能夠無限白嫖就輸出 Inf
\[ Solution \]
一瓶一瓶處理快樂水顯然是會 TLE 的,因此咱們要批量處理快樂水。class

\(~\)im

咱們開個桶 cnt[x] 表示 " 附屬品 \(x\) 的數量 " 。di

每次咱們批量處理當前的 \(n\) 瓶快樂水:while

  1. ans += n ,表示喝掉了當前的 \(n\) 瓶快樂水。
  2. cnt[i] += n ,表示獲得了這 \(m\) 個附屬品各 \(n\) 個。
  3. n += cnt[i] / a[i], cnt[i] %= a[i] ,表示用把能換的快樂水都換了。

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

\(~\)

固然,還有無限白嫖快樂水的狀況,在該狀況下,\(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 \]

相關文章
相關標籤/搜索