1. 程式人生 > >Berland Fair CodeForces - 1073D(模擬題)

Berland Fair CodeForces - 1073D(模擬題)

題意:n個數排成一個圓盤,一個人有T元錢,從第一個開始,只要他能買的,他一定會買,這樣依次迴圈,直到他的錢不能買任何物品時結束,問,他能買多少件東西。

思路:按題意模擬即可,不過T太大,考慮優化,優化的方法是當n個數的最大值都比T小,並且n個數的sum也小於T時,我們直接一次性買n個即可。

當最大值大於T時,顯然這個物品永遠都不會被買到,直接丟棄即可。

最後一種情況,當最大值小於T,但是sum大於T時,直接O(n)模擬買一次即可。

具體實現利用multiset來維護,很方便。

程式碼:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+7;
int n;
ll a[maxn];
ll T;
multiset<ll> se;
multiset<ll>::iterator it;
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    //scanf("%d",&n,&T);
    cin>>n>>T;
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        //scanf("%lld",a[i]);
        cin>>a[i];
        sum+=a[i];
       // printf("%lld\n",a[i]);
       se.insert(-a[i]);
    }
    //printf("11\n");
    ll ans=0;
    while(T>0&&se.size())
    {
        it=se.begin();
        //printf("%d %lld\n",T,sum);
        // cout<<T<<"  "<<sum<<endl;
        if(abs(*it)<=T&&sum<=T)
        {
            //cout<<1<<endl;
            ll tmp=T/sum;
            T-=tmp*sum;
            ans+=tmp*se.size();
        }
        else if(abs(*it)<=T&&sum>T)
        {
            for(int i=1;i<=n;i++)
            {
                if(se.find(-a[i])==se.end()) continue;
                if(a[i]<=T)
                {
                    T-=a[i];
                    ans++;
                }
                if(T<0) break;
            }
        }
        else
        {
            //cout<<2<<endl;
            ll tmpp=*it;
            se.erase(it);
            sum+=tmpp;
        }
    }
    printf("%lld\n",ans);
    return 0;
}