您的位置:首页 > 其它

解题报告 之 UVA11134 Fabled Rooks

2015-03-13 13:18 369 查看


解题报告 之 UVA11134 Fabled Rooks

Description





Problem F: Fabled Rooks


We would like to place n rooks, 1 ≤ n ≤ 5000, on a n×nboard subject to the following restrictions

The i-th rook can only be placed within the rectangle given by its left-upper corner (xli, yli) and its right-lower corner (xri, yri), where 1 ≤ i ≤ n,
1 ≤ xli ≤ xri ≤ n, 1 ≤ yli ≤ yri ≤ n.
No two rooks can attack each other, that is no two rooks can occupy the same column or the same row.

The input consists of several test cases. The first line of each of them contains one integer number, n, the side of the board.n lines follow giving the rectangles where the rooks can be placed
as described above. The i-th line among them gives xli,yli, xri, and yri. The input file is terminated with the integer `0' on a line by itself.
Your task is to find such a placing of rooks that the above conditions are satisfied and then outputn lines each giving the position of a rook in order in which their rectangles appeared in the input.
If there are multiple solutions, any one will do. Output IMPOSSIBLE if there is no such placing of the rooks.

Sample input

8
1 1 2 2
5 7 8 8
2 2 5 5
2 2 5 5
6 3 8 6
6 3 8 5
6 3 8 8
3 6 7 8
8
1 1 2 2
5 7 8 8
2 2 5 5
2 2 5 5
6 3 8 6
6 3 8 5
6 3 8 8
3 6 7 8
0

Output for sample input

1 1
5 8
2 4
4 2
7 3
8 5
6 6
3 7
1 1
5 8
2 4
4 2
7 3
8 5
6 6
3 7


题目大意:n*n的棋盘上有n个车,使得任意两个车不在同一列且任意两个车不在同一行。且每个车的位置在给出的两个坐标为对角线的矩形内。试构造出一种摆法。

这一题的主要注意到的是行和列没关系,按照书上的说法就是问题分解,分别考虑行和列的情况,而且是对称的。所以将二维问题分解为两个一维问题,用贪心法解题。

先考虑行,我们按照范围起点大小排序,然后尽可能输出比较靠前的位置(给后面的点留下空间)。但第二个坑点就是两个车的行范围可能有重复,如果在范围起点一致的情况下,要先处理范围小的(即范围终点),否则有可能就会误操作。所以我排序的方法是采用先按照范围起点(xl)排序,再按照范围终点(xr)排序。但是会出一个问题就是前面的某个点被占用了之后其他的点并没有更新其起点,所以我又加了一个关于m的限制,然后每一个车选择完位置之后再将未确定位置的车排序一次(其目的是更新起点)。

然后上代码:
#include <iostream>
#include <algorithm>
#define MAXN 5010
using namespace std;

struct car
{
	int xl, yl, xr, yr;
	int x, y;
	int order;
};

car cars[MAXN];
int m;

bool cmp1(const car& lhs, const car& rhs)
{
	int tem1 = lhs.xl > m ? lhs.xl : m + 1;
	int tem2 = rhs.xl > m ? rhs.xl : m + 1;
	if (tem1 == tem2)	return lhs.xr < rhs.xr;
	return tem1 < tem2;
}

bool cmp2(const car& lhs, const car& rhs)
{
	int tem1 = lhs.yl > m ? lhs.yl : m + 1;
	int tem2 = rhs.yl > m ? rhs.yl : m + 1;
	if (tem1 == tem2)	return lhs.yr < rhs.yr;
	return tem1 < tem2;
}

bool cmp3(const car& lhs, const car& rhs)
{
	return lhs.order < rhs.order;
}

int main()
{
	int n;
	while (cin >> n&&n)
	{
		for (int i = 0; i < n; i++)

		{
			cin >> cars[i].xl >> cars[i].yl >> cars[i].xr >> cars[i].yr;
			cars[i].order = i;
		}
		m = 0;
		int flag = true;
		for (int i = 0; i < n; i++)
		{
			sort(cars + i, cars + n, cmp1);
			if (m < cars[i].xr)
			{
				cars[i].x = m = max(m + 1, cars[i].xl);
			}
			else
			{
				flag = false;
				break;
			}
		}
		if (!flag)
		{
			cout << "IMPOSSIBLE" << endl;
			continue;
		}

		flag = true, m = 0;
		for (int i = 0; i < n; i++)
		{
			sort(cars + i, cars + n, cmp2);
			if (m < cars[i].yr)
			{
				cars[i].y = m = max(m + 1, cars[i].yl);
			}
			else
			{
				flag = false;
				break;
			}
		}
		if (!flag)
		{
			cout << "IMPOSSIBLE" << endl;
			continue;
		}

		sort(cars, cars + n, cmp3);
		for (int i = 0; i < n; i++)
			cout << cars[i].x << " " << cars[i].y << endl;
	}
}


哎呀一周19道看来的确是吃不消啊,,队长你看着办。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: