题目链接

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;
}