题目描述

上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的 DD 对同学上课时会交头接耳。
同学们在教室中坐成了 MMNN 列,坐在第 ii 行第$ j$ 列的同学的位置是$ (i,j),为了方便同学们进出,在教室中设置了,为了方便同学们进出,在教室中设置了 K$ 条横向的通道,LL 条纵向的通道。
于是,聪明的小雪想到了一个办法,或许可以减少上课时学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通道的位置,因为如果一条通道隔开了 22个会交头接耳的同学,那么他们就不会交头接耳了。
请你帮忙给小雪编写一个程序,给出最好的通道划分方案。在该方案下,上课时交头接耳的学生的对数最少。

输入格式

第一行,有 55 个用空格隔开的整数,分别是 M,N,K,L,D(2N,M1000,0K<M,0L<N,D2000)M,N,K,L,D(2 \le N,M \le 1000,0 \le K<M,0 \le L<N,D \le 2000)
接下来的 DD 行,每行有 44 个用空格隔开的整数。第 ii 行的 44 个整数 Xi,Yi,Pi,QiX_i,Y_i,P_i,Q_i,表示坐在位置$ (X_i,Y_i)$ 与 (Pi,Qi)(P_i,Q_i) 的两个同学会交头接耳(输入保证他们前后相邻或者左右相邻)。
输入数据保证最优方案的唯一性。

输出格式

共两行。
第一行包含 KK 个整数 a1,a2,,aKa_1,a_2,\ldots,a_K,表示第$ a_1行和行和 a_1+1$行之间、第 a2a_2行和 a2+1a_2+1行之间……第 aKa_K行和第 aK+1a_K+1行之间要开辟通道,其中 ai<ai+1a_i< a_{i+1},每两个整数之间用空格隔开(行尾没有空格)。
第二行包含LL 个整数$ b_1,b_2,\ldots,b_L$,表示第 b1b_1列和 b1+1b_1+1列之间、第 b2b_2列和 b2+1b_2+1列之间……第 bLb_L列和第$ b_L+1$ 列之间要开辟通道,其中bi<bi+1b_i< b_{i+1},每两个整数之间用空格隔开(列尾没有空格)。

输入输出样例

输入

4 5 1 2 3
4 2 4 3
2 3 3 3
2 5 2 4

输出

2
2 4

说明/提示

上图中用符号 * 、※ 、+ 标出了 33对会交头接耳的学生的位置,图中 33 条粗线的位置表示通道,图示的通道划分方案是唯一的最佳方案。

2008 年普及组第二题

题解

思路

假设过道数量没有限制,那么每出现一对会交头接耳的同学我们就要在他们中间插入一条横向或者纵向的过道。当能插入的过道的数量有限时,我们就有从中挑选能隔开人数最多的那条过道。因此,我们可以统计每横每纵能隔开人的数量,对行,选取前kk个,对列,选取前ll个。然后依次按行列的编号从大到小输出。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N=2002;
int m,n,k,l,d;
struct node
{
int people;
int id;
}column[N],row[N];
bool cmp(node a,node b)
{
return a.people>b.people;
}
vector<int>v;
void solve()
{
cin>>m>>n>>k>>l>>d;
int i;
int x,y,p,q;
for(i=0;i<N;i++)//确定行列的编号
{
column[i].id=i;
row[i].id=i;
}
for(i=1;i<=d;i++)
{
cin>>x>>y>>p>>q;
if(x==p)
{
column[min(y,q)].people++;
}
if(y==q) row[min(x,p)].people++;
}
sort(row+1,row+1+m,cmp);
sort(column+1,column+1+n,cmp);
//把选取的行列编号拿出来,排除,输出。
for(i=1;i<=k;i++)
{
v.push_back(row[i].id);
}
sort(v.begin(),v.end());
for(i=0;i<k;i++)
{
cout<<v[i];
if(i==k-1) cout<<endl;
else cout<<' ';
}
v.clear();
for(i=1;i<=l;i++)
{
v.push_back(column[i].id);
}
sort(v.begin(),v.end());
for(i=0;i<l;i++)
{
cout<<v[i];
if(i<l-1) cout<<' ';
}
}
int main()
{
solve();
return 0;
}