Solution to P7909

Chinshyo

2021-10-23 18:26:45

Solution

# [P7909(CSP2021入门组T1)](https://www.luogu.com.cn/problem/P7909) 本题是这场比赛的签到题,做法很多,给大家介绍几种常规的写法。 # 题意简述: 你手里有 $k$ 颗糖,且 $L≤k≤R$ ,$k≥n$ 。你要把糖平均分给 $n$ 个小朋友,剩下分不完的归你所有。~~啊我大赚一笔。~~ 问你最多可以~~白嫖~~获得多少糖。 # $O(R-L)$ 解法 ### 思路 这种思路非常容易想到。 暴力枚举从 $L$ 到 $K$ 的所有情况,打擂法选出最优解。这种方法竟然没有被卡。 由于要平均分给 $n$ 个小朋友,所以我们手上还剩的数量是 $k \mod n$ 。最终定格答案就是 $Max(k_i \mod n)$ 。 **此方案民间数据AC,不确保官方数据可过** ### 代码 代码提供者@[Coldling](www.luogu.com.cn/user/233576) ```cpp #include<bits/stdc++.h> using namespace std; int n,l,r,k,ans; int main(){ cin>>n>>l>>r; for(int i=l;i<=r;i++){ k=i; ans=max(ans,k%n); } cout<<ans; return 0; } ``` # $O(1)$ 解法 ### 思路 暴力枚举的方法完全是可以优化的。在枚举的过程中会产生**周期**。我们只要在这个周期内研究即可。 这边我们拿样例画图推柿子。 ![](https://cdn.luogu.com.cn/upload/image_hosting/q5pnu2to.png) 这两个图都是来源于样例中的数据,请参考样例阅读。从图中我们发现 $k_i \mod n(L≤k_i≤R)$ 的最大值有两种情况: 1. $L$ , $R$ 分布在两个不同的周期中(对应图1)。此时的答案是 $n - 1$ ,这个通过找规律可以得出。 1. $L$ , $R$ 分布在一个周期中 (对应图2)。此时为了保证答案最大,我们选择 $R \mod n$ 。 为了比较方便,我们可以事先直接把 $L$ 和 $R$ $\mod n$。 于是我们可以得出一个 **错误代码** ```cpp #include<bits/stdc++.h> using namespace std; int main() { int n, l, r; scanf("%d%d%d", &n, &l, &r); else { l = l % n; r = r % n; if(r < l) cout << n - 1 << endl; else cout << r << endl; } return 0; } ``` 为什么会错呢,那是因为如果 $L$ 和 $R$ 分别在两个不同的周期且**相隔一个周期**时,经过 $mod$ 运算后可能会被作为 $R ≥ L$ 的情况处理。因此我们只需要加上**特判**即可 $\color{green} AC$ 。 ### AC代码 ```cpp #include<bits/stdc++.h> using namespace std; int main() { //freopen("candy.in", "r", stdin); //freopen("candy.out", "w", stdout); int n, l, r; scanf("%d%d%d", &n, &l, &r); if(r - l >= n) cout << n - 1 << endl; else { l = l % n; r = r % n; if(r < l) cout << n - 1 << endl; else cout << r << endl; } return 0; } ``` ### 给各位的警示:暴力出奇迹 ![](https://cdn.luogu.com.cn/upload/image_hosting/wwu2tmcx.png)