排座椅-题解
2024-07-26 11:25:09
发布于:广东
27阅读
0回复
0点赞
题目要求输出 设置横列通道使得"交头接耳"的学生对数最少 的方案
对于最优化方案可以看出是贪心
但是贪心的策略是什么?
很显然要让通道穿过尽可能多的会讲话的同学对
即每次选择 排/列 可隔开人数数量最多的那个,选k/l次
可又但是我们如何实现这个贪心呢??
可以创建结构体数组,数组内存储两个值 1.若设置这个通道可以隔开学生的数量 2.这个为第几 行/列 的通道(Id)
而后进行排序,排序后输出前k和l个数据就行了
可又双叒但是,如何去证明这个贪心呢???
如果你的贪心策略找不出反例,那么这个思路大概就是对的awa
#include<bits/stdc++.h>
using namespace std;
int m,n,k,l,d;//M行N列,设K横道,设L纵道,D对同学 
struct SZ{int sum=0;int id;};//通道结构体 
SZ sz_p[1005];//存储 若该排上设置通道 则可以隔开多少对学生 
SZ sz_l[1005];//存储 若该列上设置通道 则可以隔开多少对学生 
bool cmp1(SZ x,SZ y){return x.sum>y.sum;}//排序可以隔开的人数,可以隔开多的在前面(最优解)
bool cmp2(SZ x,SZ y){return x.id<y.id;}//坑点:排序Id,行/列数小的在前,因为输出要去小的在前
int main() {
	cin>>m>>n>>k>>l>>d;
	for(int i=1;i<=d;i++){
		int x,y,p,q;
		cin>>x>>y>>p>>q;//这里的x,y没用,但依旧要输入一下QwQ
		//如果x轴上的不一样则代表,处于同一列不同排 存储到列sz_p数组内
		//如果y轴上的不一样则代表,处于同一排不同列 存储到列sz_l数组内
		if(x!=p&&y==q){sz_p[min(x,p)].sum+=1;sz_p[min(x,p)].id=min(x,p);} 
		else if(x==p&&y!=q){sz_l[min(y,q)].sum+=1;sz_l[min(y,q)].id=min(y,q);}
	}
	//开始排序 
	//先排序数值
    sort(sz_p****z_p+1001,cmp1);
	sort(sz_l****z_l+1001,cmp1);
	//再排序ID(输出要求)
    sort(sz_p****z_p+k+1,cmp2);
	sort(sz_l****z_l+l+1,cmp2);
	//直接输出前k和l项,因为已经把最优的前k/l项排列好了 
    //I AK YuiliceOI~~~ (不是 
	for(int i=1;i<=k;i++){cout<<sz_p[i].id<<' ';}cout<<endl;
	for(int i=1;i<=l;i++){
		cout<<sz_l[i].id<<' ';
	} 
	return 0;
}
一道贪心题,虽然标签打的贪心,但是觉得这个贪心不太凸显,即使没学过算法的也能很容易想到思路!
不过这道题在隔壁打了黄,有点Water~
这里空空如也


有帮助,赞一个