列表

详情


NC16618. [NOIP2008]排座椅

描述

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

输入描述

第一行,有 5 各用空格隔开的整数,分别是 
接下来 D 行,每行有 4 个用空格隔开的整数,第 i 行的 4 个整数 ,表示坐在位置 (X_i,Y_i)(P_i,Q_i) 的两个同学会交头接耳(输入保证他们前后相邻或者左右相邻)。
输入数据保证最优方案的唯一性。

输出描述

共两行
第一行包含 K 个整数,,表示第 a_1 行和 行之间、第 a_2 行和第 行之间、…、第 a_K 行和第 行之间要开辟通道,其中 ,每两个整数之间用空格隔开(行尾没有空格)。
第二行包含 L 个整数,,表示第 b_1 列和 列之间、第 b_2 列和第 列之间、…、第 b_L 列和第 列之间要开辟通道,其中 ,每两个整数之间用空格隔开(行尾没有空格)。

示例1

输入:

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

输出:

2
2 4

说明:

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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

pypy3(pypy3.6.1) 解法, 执行用时: 81ms, 内存消耗: 22840K, 提交时间: 2020-09-01 03:17:49

#!/usr/bin/env python3
#
# 排座椅
#
import sys, os

def read_ints(): return list(map(int, input().split()))

m, n, k, l, d = read_ints()
r = [[0, i] for i in range(m - 1)]
c = [[0, i] for i in range(n - 1)]
for _ in range(d):
	x1, y1, x2, y2 = read_ints()
	x1 -= 1; y1 -= 1; x2 -= 1; y2 -= 1
	if x1 == x2: c[min(y1, y2)][0] += 1
	elif y1 == y2: r[min(x1, x2)][0] += 1

r.sort(key=lambda x: -x[0])
c.sort(key=lambda x: -x[0])
ans1, ans2 = [], []
for i in range(k): ans1.append(r[i][1] + 1)
for i in range(l): ans2.append(c[i][1] + 1)

print(" ".join(map(str, sorted(ans1))))
print(" ".join(map(str, sorted(ans2))))

C++(clang++ 11.0.1) 解法, 执行用时: 4ms, 内存消耗: 436K, 提交时间: 2022-10-13 22:19:35

#include<bits/stdc++.h>
using namespace std;
int x[1005]={0},y[1005]={0},jx[1005]={0},jy[1005]={0},m,n,k,l,d,i,p,q,a,b;
int main(){
    cin>>m>>n>>k>>l>>d;
    for(i=1;i<=d;i++){
        cin>>p>>q>>a>>b;
        if(p==a){x[min(q,b)]+=1;jx[min(q,b)]+=1;}
        if(q==b){y[min(p,a)]+=1;jy[min(p,a)]+=1;}
    }
    sort(x+1,x+n+1),sort(y+1,y+m+1);
    int s=0;
    for(i=1;i<=m;i++) if(jy[i]>y[m-k]){cout<<i;s++;if(s<k)cout<<' ';}
    s=0;
    cout<<'\n';
    for(i=1;i<=n;i++) if(jx[i]>x[n-l]){cout<<i;s++;if(s<l)cout<<' ';}
    return 0;
}

Python3(3.5.2) 解法, 执行用时: 24ms, 内存消耗: 3800K, 提交时间: 2020-08-10 22:47:51

from collections import defaultdict
n, m, k, l, d = map(int, input().split())
row = defaultdict(int)
line = defaultdict(int)
for i in range(d):
    x, y, p, q = map(int, input().split())
    if x == p:
        line[min(y, q)] += 1
    else:
        row[min(x, p)] += 1
ar = sorted(row, key=lambda z: -row[z])[:k]
ar.sort()
al = sorted(line, key=lambda z: -line[z])[:l]
al.sort()
print(' '.join(map(str, ar)))
print(' '.join(map(str, al)))

上一题