这道题的思路是贪心,为什么是贪心呢,因为能划分的行、列过道都是有限个数,要是想在有限个数里面选取最优解,那显然是找同一个两行里面交头接耳人数最多的两行中间加过道,列也是如此。

不过这里有坑点,就是他要求输出时候下标要升序排序,样例也是鸡贼,不对下标排序的话能过,然后我就开心的提交了,然后就G了,所以下标也要拍一次序,当然要在选出的那L或者K个大值中排序。

#include<bits/stdc++.h>
using namespace std;
int m,n,k,L,d;
const int M=2e4+5;
struct node{
	int ind,cnt;
	bool operator<(const node &a)const{
		return cnt>a.cnt;
	}
};
bool cmp(node a,node b){
    return a.ind<b.ind;
}
node h[M];
node l[M];
int main(){
	cin>>m>>n>>k>>L>>d;
	for(int i=1;i<=m;i++) h[i].ind=i;
	for(int j=1;j<=n;j++) l[j].ind=j;
	for(int i=1;i<=d;i++){
		int x,y,p,q;
		cin>>x>>y>>p>>q;
		if(y==q) h[((x<p)? x:p)].cnt++;
		if(x==p) l[((y<q)? y:q)].cnt++; 
	}
	sort(h+1,h+1+m);
	sort(l+1,l+1+n);
    sort(l+1,l+1+L,cmp);
    sort(h+1,h+1+k,cmp);
//	for(int i=1;i<=n;i++){
//		cout<<l[i].ind<<" "<<l[i].cnt<<endl;
//	}
	for(int i=1;i<=k;i++){
		cout<<h[i].ind<<" ";
	}
	cout<<'\n';
	for(int i=1;i<=L;i++){
		cout<<l[i].ind<<" ";
	}
	cout<<'\n';
	return 0;
}