1. 程式人生 > 其它 >C++-分糖果 解題思路

C++-分糖果 解題思路

【Horn Studio】程式設計專欄: 分糖果  解題思路

題目

題目描述

紅太陽幼兒園有 nn 個小朋友, 你是其中之一。保證 n2n≥2 。
有一天你在幼兒園的後花園裡發現無窮多顆糖果, 你打算拿一些糖果回去分給幼兒園的小朋友們。 由於你只是個平平無奇的幼兒園小朋友, 所以你的體力有限, 至多隻能拿 RR 塊糖回去。 但是拿的太少不夠分的, 所以你至少要拿 LL 塊糖回去。保證 nLRn≤L≤R 。 也就是說, 如果你拿了 kk 塊糖, 那麼你需要保證 LkRL≤k≤R 。
如果你拿了 kk 塊糖, 你將把這 kk 塊糖放到籃子裡, 並要求大家按照如下方案分糖果:只要籃子裡有不少於 
nn
 塊糖果,幼兒園的所有 nn 個小朋友(包括你自己)都從籃子中拿走恰好一塊糖, 直到籃子裡的糖數量少 於 nn 塊。此時籃子裡剩餘的糖果均歸你所有一一這些糖果是作為你搬糖果的獎勵。
作為幼兒園高質量小朋友, 你希望讓作為你搬糖果的獎勵的糖果數量(而不是你最後獲得的總糖果數 量!)儘可能多; 因此你需要寫一個程式, 依次輸入 n,L,Rn,L,R, 並輸出你最多能獲得多少作為你搬糖果的獎 勵的糖果數量。

輸入

輸入一行, 包含三個正整數 $n, L, R$, 分別表示小朋友的個數、糖果數量的下界和上界。

輸出

輸出一行一個整數,表示你最多能獲得的作為你搬糖果的獎勵的糖果數量。

樣例輸入 複製

7 16 23

樣例輸出 複製

6

提示

對於所有資料, 保證 2nLR1092≤n≤L≤R≤109 。

來源

思路

雙做法:

1.暴力

只需要判斷一下r-小於等於l的n的倍數中最大的數

用ans來記錄一下 ans=r-(l/n*n);

如果ans>=n就肯定可以帶回去<n中最大的糖果數目也就是n-1,不然ans就是它最大能帶走的糖果數目

果然,複雜度是O(R-L),絕對tle!所以,我們需要轉化一下……

2.數學思想(普通)

首先看到十分恐怖的數字,RL1e9,我們需要使用數學思想……

只需要判斷一下r-小於等於l的n的倍數中最大的數

用ans來記錄一下 ans=r-(l/n*n);

如果ans>=n就肯定可以帶回去<n中最大的糖果數目也就是n-1,不然ans就是它最大能帶走的糖果數目

 這並不會tle,也是其中一種辦法。

3.數學思想(精簡)

先嚐試將餘數補到n-1,如果超過r,那麼結果就是r mod n,否則就是n-1。

程式碼 暴力

#include<bits/stdc++.h>
using namespace std;
int n,l,r;
int ans=-1;
int main(){
	scanf("%d%d%d",&n,&l,&r);
	for(int i=r;i>=l;i--){
		int k=i;
		while(k-n>0){
			k-=n;
		}if(k!=n) ans=max(ans,k);
	}printf("%d",ans);
	return 0;
} 
//12345code佐助題庫提交結果:TLE 18%,超時3個點

程式碼 數學思想1:

#include<bits/stdc++.h>
using namespace std;
long long n,l,r,ans;
int main() {
	scanf("%lld%lld%lld",&n,&l,&r);
	ans=r-(l/n*n);
	if(ans>=n) {
		printf("%lld",n-1);
	} else {
		printf("%lld",ans);
	}
	return 0;
}//12345code佐助題庫提交結果:AC

程式碼 數學思想2:

#include<bits/stdc++.h>
using namespace std;
int n,l,r;
int main(){
	cin>>n>>l>>r;
	cout<<min(r,l+(n-1-l%n))%n;
	return 0;
}

彩蛋