版权声明:转载请在原文附上源连接以及作者,谢谢~ https://blog.csdn.net/weixin_39778570/article/details/83752308
ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443
题目:https://www.luogu.org/problemnew/show/P1056
解法:
输入数据保证最优方案的唯一性。所以一定有一个唯一解啦。。。 好像是使用贪心的敏感词 (题还是做得太少了)
单独看行一条通道能隔开越多的人越划算,
单独看列一条通道能隔开越多的人越划算,
但是合起来可以吗?仔细一想,如果一行上有两个相邻的同学说话,只要把列隔开,行怎么隔都不能影响到列,同理列怎么隔也都不能影响到行。所以行列是无印象的,可分开计算没隔开一行或者一列所产生的贡献(隔开人数),贪心按贡献从大到小把矩形分割开来。
如果解不确定就不行,划分有多种。但是题目说了解确定啊。。。
预处理一下每一行和每一列交头接耳的的同学的数量(同行,相邻列,隔开的时候取小的,所以取小的列,行同理)
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
struct node{
int val,idx;
bool operator < (const node &b)const{return val>b.val;}
}H[1005],L[1005];
int m,n,k,l,d;
vector<int> ver;
int main(){
cin>>m>>n>>k>>l>>d;
int x1,x2,y1,y2;
fo(i,1,1005)L[i].idx=H[i].idx=i;
fo(i,1,d){
cin>>x1>>y1>>x2>>y2;
if(x1==x2){ // 同行
L[min(y1,y2)].val++;
}else{ // 同列
H[min(x1,x2)].val++;
}
}
sort(H+1,H+1+n);
fo(i,1,k)ver.push_back(H[i].idx);
sort(ver.begin(),ver.end());
fo(i,0,k-1)printf("%d%c",ver[i],i==k-1?'\n':' ');
ver.clear();
sort(L+1,L+1+m);
fo(i,1,l)ver.push_back(L[i].idx);
sort(ver.begin(),ver.end());
fo(i,0,l-1)printf("%d%c",ver[i],i==l-1?'\n':' ');
return 0;
}