题目链接
https://www.luogu.com.cn/problem/P7107
解题思路
https://www.luogu.com.cn/blog/291706/solution-p7107
贪心的思路还是比较简单的,但是代码细节的实现还是有点难的。
下面的代码会着重强调一些细节
说是贪心又像模拟
AC代码
#include<bits/stdc++.h> #define ll long long using namespace std; int main() { int n,p; ll m,k; cin>>n>>m>>k>>p; if(k==0) { if(p==n) { puts("YES"); for(int i=1;i<=n;i++) cout<<0<<' '<<m<<endl; } else puts("NO"); return 0; } if(p>k) { puts("NO"); return 0; } ll div=k/p,mod=k%p; div=min(div,m);//!!!最多拿m个,而且即使商大于m,也可以试着让p个人取m个 mod=k-div*p; if(mod) { if(n==p) puts("NO"); else { ll tdiv=mod/(n-p),tmod=mod%(n-p);//剩下的人分多出来的 if(tmod && tdiv+1>=div)//非整除,tdiv+1是剩下的n-p个人中最大的持有量 { puts("NO"); return 0; } else if(!tmod && tdiv>=div)//整除,tdiv是剩下的n-p个人中最大的持有量 { puts("NO"); return 0; } puts("YES"); for(int i=1;i<=p;i++) cout<<div<<' '<<m-div<<endl; for(int i=p+1;i<=p+tmod;i++) cout<<tdiv+1<<' '<<m-tdiv-1<<endl; for(int i=p+tmod+1;i<=n;i++) cout<<tdiv<<' '<<m-tdiv<<endl; } } else { puts("YES"); for(int i=1;i<=p;i++) cout<<div<<' '<<m-div<<endl; for(int i=p+1;i<=n;i++) cout<<0<<' '<<m<<endl; } return 0; }