题目链接
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;
}

京公网安备 11010502036488号