1. 程式人生 > 實用技巧 >校內模擬賽補題筆記

校內模擬賽補題筆記

2020.9.12

A. 售貨機

題意:
你有 \(b\) 張價值 \(10^6\) 元的紙幣和 \(c\) 張價值 \(1\) 元的硬幣。
現在有一臺賣脈動的自動售貨機,脈動的單價為 \(r\) 元。最初裡面有 \(d\) 個一元硬幣用於找零。
買脈動的流程如下:

  • 假設你投入了 \(x\) 張價值為 \(10^6\) 紙幣和 \(y\)\(1\) 元硬幣,設 \(z=10^6 \times +y\)
  • 如果 \(z<r\),那麼自動售貨機肯定不會把脈動賣給你,並且它會退回全部的錢。
  • 如果 \(z \geq r\),那麼自動售貨機會嘗試著用原來已有的硬幣來找零。即,如果自動售貨機裡原有的錢數 \(w \geq z-r\)
    ,那麼它就會收下你投入的錢(這些錢可以下次用於找零),並給你 \(z-r\) 個硬幣。
    問你最多可以買到多少瓶脈動。
    \(b,c,r,d \leq 10^9\)

容易注意到自動售貨機與你手上的 \(1\) 元硬幣總數是定值。
進而我們就會發現一個性質:如果 \(c+d \geq 10^6\),那麼你擁有的總錢數能夠支付起多少瓶脈動,你就可以得到多少瓶脈動。
簡單證明一下,假設 \(x=r \bmod 10^6\),並且現在你擁有的總錢數達到了一瓶脈動的價格 \(r\)
如果你手上現有的 \(1\) 元硬幣個數 \(t \geq x\),那麼你一定可以剛好湊出 \(r\) 元。
如果你手上現有的 \(1\)

元硬幣個數 \(t<x\),那麼售貨機裡零錢的個數 \(=c+d-t \geq 10^6-t\),也就是說,即使你給它若干個紙幣,售貨機裡的硬幣也夠找你錢。
故我們只用考慮 \(c+d<10^6\) 的情況。
我們暴力地列舉買的瓶數,然後檢驗一下就可以了。
為什麼這樣子就行了呢?因為如果你發現到某一時刻自動售貨機不能找錢,那麼一定有 \(t<x\)。列舉 \(10^6\) 步一定可以列舉到這個時刻。

#define int long long
int b=read(),c=read(),r=read(),d=read();
signed main(){
	int ans=(1000000ll*b+c)/r;
	if(c+d>=1000000) return cout<<ans<<endl,0;
	for(int i=1;i<=1000000;i++){
		int t=i*r%1000000ll;
		if(t>c&&t+d<1000000){
			cout<<min(i-1,ans)<<endl;
			return 0;
		}
	}
	cout<<ans<<endl;
	return 0;
}