【NOIP2008普及组复赛】 题2:排座椅

题2:排座椅

(seat.pas/c/cpp)(seat.pas/c/cpp)(seat.pas/c/cpp)

# 【题目描述】

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

请你帮忙给小雪编写一个程序,给出最好的通道划分方案。在该方案下,上课时交头接耳的学生的对数最少。

# 【输入文件】

输入文件seat.inseat.inseat.in的第一行,有555个用空格隔开的证书,分别是M,N,K,L,DM,N,K,L,DM,N,K,L,D(2≤N,M≤1000,0≤K<M,0≤L<N,D≤2000)(2≤N,M≤1000,0≤K<M,0≤L<N,D≤2000)2N,M1000,0K<M,0L<N,D2000

接下来DDD行,每行有444个用空格隔开的整数。第iii行的444个证书Xi,Yi,Pi,OiX_i,Y_i,P_i,O_iXiYiPiOi,表示坐在位置(Xi,YiX_i,Y_iXiYi)与(Pi,OiP_i,O_iPiOi)的两个同学会交头接耳(输入保证他们前后相邻或者左右相邻)。

输入数据保证最优秀方案的唯一性。

# 【输出文件】

输出文件seat.ouseat.ouseat.ou共两行。

第一行包含KKK个整数,a1,a2……aka_1,a_2……a_ka1,a2……ak,表示第a1a_1a1行和a1+1a_1+1a1+1行之间、第a2a_2a2行和第a2+1a_2+1a2+1行之间、…、第a_K
行和第aK+1a_K+1aK+1行之间要开辟通道,其中ai<ai+1ai<ai+1aiai+1,每两个整数之间用空格隔开(行尾没有空格)。

第二行包含LLL个整数,b1b2……bLb_1b_2……b_Lb1b2……bL,表示第b1b_1b1列和b1+1b_1+1b1+1列之间,第b2b_2b2列和b2+1b_2+1b2+1列之间、…、第bLb_LbL列和第bL+1b_L+1bL+1列之间要开辟通道,其中bi<bi+1b_i<b_i+1bibi+1,每两个整数之间用空格隔开(行尾没有空格)。

# 【输入样例1】 seat.in

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

# 【输出样例1】 seat.ou

2
2 4

【输入输出样例解释】

在这里插入图片描述
上图中用符号∗、※,+*、※,++标出了333对会交头接耳的学生的位置,图中3条粗线的位置表示通道,图示的通道划分方案是唯一的最佳方案。

【代码如下】:

#include <bits/stdc++.h>
using namespace std;
int M, N, K, L, D;
int x, y, p, q;
typedef struct tagINT {
  int ID;
  int entity;
} INT;
INT l[1020], t[1020], temp;
void save(int x, int y, int p, int q) {
  if (x == p) {
    l[min(y, q)].entity++;
    return;
  } else {
    t[min(x, p)].entity++;
    return;
  }
}
int main() {
  cin >> M >> N >> K >> L >> D;
  for (int i = 0; i < D; i++) {
    cin >> x >> y >> p >> q;
    save(x, y, p, q);
  }
  for (int i = 1; i <= M; i++) l[i].ID = i;
  for (int i = 1; i <= N; i++) t[i].ID = i;
  for (int i = 1; i <= M; i++) {
    for (int j = i + 1; j <= M; j++) {
      if (t[i].entity < t[j].entity) swap(t[i], t[j]);
    }
  }
  for (int i = 1; i <= N; i++) {
    for (int j = i + 1; j <= N; j++) {
      if (l[i].entity < l[j].entity) swap(l[i], l[j]);
    }
  }
  for (int i = 1; i <= K; i++) {
    for (int j = i + 1; j <= K; j++) {
      if (t[i].ID > t[j].ID) swap(t[i], t[j]);
    }
  }
  for (int i = 1; i <= L; i++) {
    for (int j = i + 1; j <= L; j++) {
      if (l[i].ID > l[j].ID) swap(l[i], l[j]);
    }
  }
  for (int i = 1; i <= K; i++) {
    if (i > 1) cout << ' ';
    cout << t[i].ID;
  }
  cout << endl;
  for (int i = 1; i <= L; i++) {
    if (i > 1) cout << ' ';
    cout << l[i].ID;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lpstudio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值