题目:
样例解释:
样例1解释
拿 k=20 块糖放入篮子里。
篮子里现在糖果数 20≥n=7,因此所有小朋友获得一块糖;
篮子里现在糖果数变成 13≥n=7,因此所有小朋友获得一块糖;
篮子里现在糖果数变成 6<n=7,因此这 6 块糖是作为你搬糖果的奖励。
容易发现,你获得的作为你搬糖果的奖励的糖果数量不可能超过 6 块(不然,篮子里的糖果数量最后仍然不少于 n,需要继续每个小朋友拿一块),因此答案是 6。
样例2解释
容易发现,当你拿的糖数量 k 满足 14=L≤k≤R=18 时,所有小朋友获得一块糖后,剩下的 k−10 块糖总是作为你搬糖果的奖励的糖果数量,因此拿 k=18 块是最优解,答案是 8。
思路:
70分思路:
暴力枚举 [l,r][l,r] 中的每一个整数并统计答案。
100分思路:
取余运算的两个简单性质:
(大概是小学知识吧)
nn 对任何正整数取余的结果都在 [0,n−1][0,n−1]范围内
若 x mod n=yxmodn=y,则 (x+n) mod n=y(x+n)modn=y
因此我们能知道:
若 r−l+1≥nr−l+1≥n,则 [0,n−1][0,n−1] 中的每个正整数都能在 [l,r][l,r]中的正整数对 nn 取余的结果中找到,此时答案为 n−1n−1
若 r−l+1<nr−l+1<n,则再分类讨论:
若 l mod n≤r mod nlmodn≤rmodn,如下图
此时能取到的数的范围为上图的红色部分,这时答案为 r mod nrmodn
注意: 这里的分类是 l mod n≤r mod n l mod n≤r mod n,而非 l mod n<r mod n l mod n<r mod n
若 l mod n>r mod n lmod n>r mod n,如下图
此时能取到的数的范围为上图的红色部分,这时答案为 n−1
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int n,l,r;
int main(){
cin>>n>>l>>r;
if(l/n==r/n) cout<<r%n;
else cout<<n-1;
return 0;
}
总结:
此题解题关键为分类讨论,必须贯彻不重不漏的原则,否则有可能出错