题意:
在一个m*n的教室中,有D对交头接耳的同学,你可以用k行l列隔开,问怎么隔开上课时交头接耳的学生对数最少?

思路:
我们可以发现列和行之间没有联系,所以行列分别单纯贪心从最多隔断到最少。
注意:输出结果时两行答案是升序的。

代码:

#include <bits/stdc++.h>
typedef long long ll;

using namespace std;

const ll inf=998244353;

inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

struct w
{
    int k, v;
}c[1005], r[1005];

bool cmp(struct w a,struct w b)
{
    return a.v>b.v;
}

bool cmp1(struct w a,struct w b)
{
    return a.k<b.k;
}

int main()
{
    int n, m, k, l, q;
    scanf("%d%d%d%d%d",&n,&m,&k,&l,&q);
    for(int i=0;i<=1005;i++)
    {
        c[i].k=i;
        c[i].v=0;
        r[i].k=i;
        r[i].v=0;
    }
    while(q--)
    {
        int x, y, x2, y2;
        scanf("%d%d%d%d",&x,&y,&x2,&y2);
        if(x==x2)
        {
            c[min(y,y2)].v++;
        }
        else
        {
            r[min(x,x2)].v++;
        }
    }
    sort(c,c+1005,cmp);
    sort(r,r+1005,cmp);
    sort(c,c+l,cmp1);
    sort(r,r+k,cmp1);
    for(int i=0;i<k;i++)
    {
        printf("%d%c",r[i].k,i+1==k?'\n':' ');
    }
    for(int i=0;i<l;i++)
    {
        printf("%d%c",c[i].k,i+1==l?'\n':' ');
    }
    return 0;
}