#include<bits/stdc++.h>
#define ll long long
#define maxsize 200100
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int n;
ll t,sum,a[maxsize],ans,now;
int main()
{
while(cin>>n>>t)
{
sum=0;
ans=now=0;
for(int i=1;i<=n;++i) cin>>a[i];
while(1)
{
for(int i=1;i<=n;++i)
{
if(t>=a[i])
{
t-=a[i];
sum+=a[i];
ans++;
now++;
}
}
if(now==0) break;
ans+=t/sum*now;
t=t%sum;
now=0;sum=0;
}
cout<<ans<<endl;
}
return 0;
}
(code來源:https://blog.csdn.net/qq_38735931/article/details/83443583)
題意:
初始有t元,每次從1開始買椅贱,從1到n依次有n個人填硕,每個人的東西價格為a[i]颠区,該人依次能買就買娜饵,到n之后再回到1從頭開始瞻惋,問最后能買到的東西數(shù)量(參考:http://www.cnblogs.com/myx12345/p/9858179.html)
code解釋:(自己寫的)
一開始如果按照正常的暴力的思路的話括袒,就直接while(t>=min(a))
{
for(1->n):
if(t>=a[i]):
t-=a[i];
sum++;
}
cout<<sum<<endl;
這樣就完事了次兆,但是由于T是1e18非常大,所以絕對會TLE锹锰,所以需要換一種思路芥炭。
結(jié)合上面的CODE,發(fā)現(xiàn)恃慧,用兩個循環(huán):外循環(huán)控制是不是還能轉(zhuǎn)圈园蝠,內(nèi)循環(huán)控制統(tǒng)計能買到的個數(shù)。
注意兩個特殊的數(shù)據(jù):now,sum
注意ans的加的值有兩個:t/sumnow,++1
現(xiàn)在來解釋一下:
首先痢士,now表示的是能買到的個數(shù)彪薛,sum表示能買到的所有價格的總和數(shù)。
ans加的第一個值是t/sum*now怠蹂,這個表是什么意思善延?
這個表示的是,比如現(xiàn)在剛剛轉(zhuǎn)完一圈城侧,那么易遣,我也統(tǒng)計了now,sum,那么為了減少循環(huán)的次數(shù),我就要把當(dāng)前的(now,sum)當(dāng)作一個周期嫌佑,隨著我不斷的轉(zhuǎn)圈豆茫,周期的(now,sum)會不斷減小,但是每一個周期的轉(zhuǎn)圈次數(shù)不一定是一樣的(在一個周期里面歧强,now和sum都是一樣的)澜薄,這樣,就可以用乘法原理直接把當(dāng)前的ans加上t/sum(表示這個周期我能轉(zhuǎn)幾圈)摊册,之后乘上now(乘法原理肤京,乘上這個周期的買到的東西的數(shù)量)
那還有一個++1又是什么呢?這個表示我在這一個周期的第一次轉(zhuǎn)圈中,如果能買茅特,就讓ans+1;
之后就是整個程序的核心了:
t=t%sum忘分,這個表示的是我消耗完這個周期,那么剩下的余數(shù)肯定會小于當(dāng)前的sum白修,從而大大的降低了循環(huán)的次數(shù)妒峦,使得整個程序的時間復(fù)雜度變成了評測系統(tǒng)可以接受的程度。