【题解】排座椅
作者:互联网
题目描述
上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳。同学们在教室中坐成了M行N列,坐在第i行第j列的同学的位置是(i,j),为了方便同学们进出,在教室中设置了K条横向的通道,L条纵向的通道。于是,聪明的小雪想到了一个办法,或许可以减少上课时学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通道的位置,因为如果一条通道隔开了两个会交头接耳的同学,那么他们就不会交头接耳了。
请你帮忙给小雪编写一个程序,给出最好的通道划分方案。在该方案下,上课时交头接耳的学生对数最少。
输入格式
第一行,有五个用空格隔开的整数,分别是M,N,K,L,D(2≤N,M≤1000;0≤K<M;0≤L<N,D≤2000);
接下来D行,每行有4个用空格隔开的整数,第i行的4个整数Xi,Yi,Pi,Qi,表示坐在位置(Xi,Yi)与(Pi,Qi)的两个同学会交头接耳(输入保证他们前后相邻或者左右相邻)。
输入数据保证最优方案的唯一性。
输出格式
共两行:
第一行包含K个整数,a1,a2,......,ak,表示第a1行和a1+1行之间、第a2行和第a2+1行之间、......、第ak行和第ak+1行之间要开辟通道,其中ai<ai+1,每两个整数之间用空格隔开(行尾没有空格)。
第二行包含L个整数,b1,b2,......,bk,表示第b1列和b1+1列之间、第b2列和第b2+1列之间、......、第bl列和第bl+1列之间要开辟通道,其中bi<bi+1,每两个整数之间用空格隔开(行尾没有空格)。
输入样例
4 5 1 2 3
4 2 4 3
2 3 3 3
2 5 2 4
输出样例
2
2 4
题解
容易想到,根据当前行或列的交头接耳人数进行排序,取前$k$或$l$大的分出过道即可。
#include <iostream> #include <algorithm> #include <cmath> #include <cstdio> #include <queue> #define MAXM 1001 #define MAXN 1001 #define MAXD 2001 using namespace std; int m, n; int k, l; int d; int x, y, p, q; struct node { int num; int idx; }kn[MAXM], ln[MAXN]; priority_queue <int, vector<int>, greater<int> > ans; bool cmp(node a, node b) {return a.num > b.num;}; int main() { scanf("%d%d%d%d%d", &m, &n, &k, &l, &d); for(register int i =1 ; i <= d; i++) { scanf("%d%d%d%d", &x, &y, &p, &q); if(x == p)// 左右交头接耳 { ln[min(y, q)].num++; // 记录交头接耳人数 } else // 上下交头接耳 { kn[min(x, p)].num++; // 同上 } } for(register int i = 1; i < m; i++) kn[i].idx = i; for(register int i = 1; i < n; i++) ln[i].idx = i; sort(kn + 1, kn + m, cmp); // 按照交头接耳的同学对数来排序 sort(ln + 1, ln + n, cmp); // 同上 int op = 0; for(register int i = 1; i <= k; i++) ans.push(kn[i].idx); while(!ans.empty()) { if(op++) putchar(' '); printf("%d", ans.top()); ans.pop(); } putchar('\n'); op = 0; for(register int i = 1; i <= l; i++) ans.push(ln[i].idx); while(!ans.empty()) { if(op++) putchar(' '); printf("%d", ans.top()); ans.pop(); } return 0; }参考程序
标签:同学,空格,int,题解,整数,交头接耳,座椅,include 来源: https://www.cnblogs.com/kcn999/p/10800386.html