题解 P1056 【排座椅】

由于题中多次提到“最优方案”与“最好的”等词语,很容易想到这题要使用贪心。

由题可知,我们要尽量多的将交头接耳的同学隔开,而题中已给出过道的行数与列数,因此我们只需要找到隔开交头接耳同学数量最多的K条横向的通道和L条纵向的通道。

操作步骤如下

  1. 用结构体记录相应的量(方便后期操作)。
  2. 在读入同学坐标时,记录每条通道能隔开的数量。(若xp,则过道为(y+q)/2;若yq,则过道为(x+p)/2)
  3. 排序,输出。

代码:

#include <iostream>
#include <algorithm>
using namespace std;
struct con{               //定义结构体
	int x,y;   //同学1坐标
	int p,q;   //同学2坐标
	int b,c;   //b为横向通道数,c为纵向通道数
	int pp;    //编号
}a[2200];
int comp1(const con &x,const con &y)  //排序函数(将横向通道数目从大到小排)
{
	return x.b>y.b;
}
int comp2(const con &x,const con &y)  //排序函数(将纵向通道数目从大到小排)
{
	return x.c>y.c;
}
int comp3(const con &x,const con &y)  //排序函数(将编号从小到大排)
{
	return x.pp<y.pp;
}
int m,n,k,l,d;
int main()
{
	int i,j;
	cin>>m>>n>>k>>l>>d;                 //输入,如题。
	for(i=1;i<=2200;i++) a[i].pp=i;        //编号。
	for(i=1;i<=d;i++)
	{
		cin>>a[i].x>>a[i].y>>a[i].p>>a[i].q;
		if(a[i].q==a[i].y) a[(a[i].p+a[i].x)/2].b++;
		else a[(a[i].q+a[i].y)/2].c++;            //记录隔开同学数目,状态。
	}
	sort(a+1,a+1+1000,comp1);                  //将隔开同学数从大到小排。
	sort(a+1,a+1+k,comp3);                    //记得编号要从小到大输出
	for(i=1;i<=k;i++) cout<<a[i].pp<<" ";
	cout<<endl;
	sort(a+1,a+1+1000,comp2);                  //同上
	sort(a+1,a+1+l,comp3);                    //同上
	for(i=1;i<=l;i++) cout<<a[i].pp<<" ";
	return 0;
}

完...

posted @ 2020-12-02 12:03  -lala-  阅读(155)  评论(0)    收藏  举报