刷题记录:牛客NC16618排座位

传送门:牛客

题目描述:

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

当年普及组的一道题,洛谷上普及难度

主要思路:

  1. 首先题设有一个很重要的辅助条件,那就是交互的两个同学一定是两隔壁的,这就为我们提供了很好的帮助作用,我们想一下,既然需要求的是如何让交投接耳的同学对数最少也就是被我们通道隔开的同学数量最多.也就是通道两边的同学数量最多
  2. 很显然我们需要对横排和竖排进行分类的,分别记录每一行和每一列的同学数量即可,最后从大到小排个序,择优而取即可,因为MN的数据并不大,因此在这里可以直接使用n^2的排序复杂度也照样可以过关,在这里我使用的是一种**排序(我好像并不知道这种排序的名字,具体来说就是比较比自己大的有几个,从而得出自己所排的位置)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string.h>
#include <stack>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
	ll x=0,w=1;char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
	return x*w;
}
#define maxn 1000000
int lie[2000],hang[2000];
int index_lie[2000],index_hang[2000];
int main() {
	int M,N,K,L,D;
	M=read(),N=read(),K=read(),L=read(),D=read();
	int xi,yi,pi,qi;
	for(int i=1;i<=D;i++) {
		xi=read(),yi=read(),pi=read(),qi=read();
		if(xi==pi) {
			lie[min(yi,qi)]++;
		}else {
			hang[min(xi,pi)]++;
		}
	}
	for(int i=1;i<=M;i++) {
		for(int j=1;j<=M;j++) {
			if(i==j) continue;
			if(hang[i]<hang[j]) index_hang[i]++;
		}
	}
	for(int i=1;i<=N;i++) {
		for(int j=1;j<=N;j++) {
			if(i==j) continue;
			if(lie[i]<lie[j]) index_lie[i]++;
		}
	}
	for(int i=1;i<=M;i++) {
		if(index_hang[i]<=K-1) {
			cout<<i<<" ";
		}
	}
	cout<<endl;
	for(int i=1;i<=N;i++) {
		if(index_lie[i]<=L-1) {
			cout<<i<<" ";
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值