排座椅:贪心+排序
https://ac.nowcoder.com/acm/problem/16618
思路:
1)先单独看左右相邻的情况。贪心策略就是优先把某一列对数多的相邻两列插入一个纵向通道,所有统计每列上有多少对,按这个排好序后然后再去出l个按下标排序,最后就是纵向通到的答案。
2)同理上下相邻也是一样的。
#include <bits/stdc++.h>
#define ull unsigned long long
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 10007;
const int N = 2e3+7;
const int ds = 1e8+7;
const double PI = 3.141592653589793238462643383;
using namespace std;
struct node{
int x,cs;
}node1[N],node2[N];
int cnt1[N],cnt2[N],ans1[N],ans2[N];
bool cmp(node a,node b){
if(a.cs == b.cs) return a.x < b.x;
return a.cs > b.cs;
}
void solve() {
int n,m,k,l,d;
int t1 = 0,t2 = 0,l1 = 0,l2 = 0;
scanf("%d%d%d%d%d",&m,&n,&k,&l,&d);
for(int i = 1; i <= d; i++){
int x,y,p,q;
scanf("%d%d%d%d",&x,&y,&p,&q);
if(x == p){
int yy = min(y,q);
cnt1[yy]++;
}
else{
int xx = min(x,p);
cnt2[xx]++;
}
}
for(int i = 1; i <= n; i++){
if(cnt1[i]) {
node1[l1].x = i;
node1[l1++].cs = cnt1[i];
}
}
for(int i = 1; i <= m; i++) {
if(cnt2[i]) {
node2[l2].x = i;
node2[l2++].cs = cnt2[i];
}
}
sort(node1,node1+l1,cmp);
sort(node2,node2+l2,cmp);
l1 = min(l1,l);
l2 = min(l2,k);
for(int i = 0; i < l2; i++){
ans1[i] = node2[i].x;
}
for(int i = 0; i < l1; i++){
ans2[i] = node1[i].x;
}
sort(ans1,ans1+l2);
sort(ans2,ans2+l1);
for(int i = 0; i < k && i < l2; i++){
if(i == 0) printf("%d",ans1[i]);
else printf(" %d",ans1[i]);
}
printf("\n");
for(int i = 0; i < l && i < l1; i++){
if(i == 0) printf("%d",ans2[i]);
else printf(" %d",ans2[i]);
}
}
int main() {
// int t;
// scanf("%d",&t);
// while(t--)
solve();
return 0;
}