Bootstrap

CSP-J 2008 排座椅

[NOIP2008 普及组] 排座椅 - 洛谷


解题思路:

1.这道题有一个很大的坑点就是每一对交头接耳的同学是固定的,而不是任意挨着的一对交头接耳的同学就算一对,所以刚开始的方向数组的思路是不正确的。

2.那么输入数据保证是左右相邻的一对学生,只要在输入的时候进行判断这两个同学是一行还是一列,利用桶排序的思想,将需要隔开的列号或者行号的值存起来累加即可

3.所以这道题的思路是贪心,因为行的通道数和列的通道数是固定的,我们只要按照数量大小,选出前k个行号和前l个列号,然后按照从小到大的序号输出即可,因为数据范围较小,所以同样可以利用桶排,最后把非空桶输出即可


#include<bits/stdc++.h>
using namespace std;
int ans1[1010],ans2[1010],ans3[1010],ans4[1010];
int main()
{
	int m,n,k,l,d;
	cin>>m>>n>>k>>l>>d;
	int x1,y1,x2,y2;
	for(int i=1;i<=d;i++)
	{
		cin>>x1>>y1>>x2>>y2;
		if(x1==x2)//如果行号相等 
		{
			ans2[min(y1,y2)]++;//则较小值的列数加1 
		}
		else//如果列号相等 
		{
			ans1[min(x1,x2)]++; //较小值的行数加
		} 
	}
	for(int i=1;i<=k;i++)//找k条横向通道 
	{
		int max=-1;//初始化最大值 
		int flag;
		for(int j=1;j<=m-1;j++)
		{
			if(ans1[j]>max)
			{
				max=ans1[j];
				flag=j;
			}//找到最大值的编号,并赋值给flag 
		}
		ans1[flag]=0;//该位置元素值清零 
		ans3[flag]++;//桶排序 
	}
	for(int i=1;i<=l;i++)//找l条纵向通道
	{
		int max=-1;
		int flag;
		for(int j=1;j<=n-1;j++)
		{
			if(ans2[j]>max)
			{
				max=ans2[j];
				flag=j;
			}
		}
		ans2[flag]=0;
		ans4[flag]++;
	}
	for(int i=1;i<=1010;i++)
	{
		if(ans3[i]!=0)
		cout<<i<<" ";
	}
	cout<<endl;
	for(int i=1;i<=1010;i++)
	{
		if(ans4[i]!=0)
		cout<<i<<" ";
	}
	return 0;
}

;