UVA 11134 Fabled Rooks

题意:

  给你一个n*n的棋盘,让你在棋盘上放n个棋子,要求是所有棋子不能相互攻击(同行或者同列就会攻击),并且每个棋子都有一个限制,那就是必须在给定的矩形r[i]里,输出每个棋子的位置。

分析:

  这个题看的是别人的题解。然后我们从前往后贪心,右端点越小的“自由性”越小,所以要先处理,所以放在前面,对于每一断,我们就从这个段的做端点开始找,找第一个没被占用的点,占用上就行了,如果都找到右端点了还没找到可以用的点,那么就直接没解了,x和y都是这么处理的。

代码:

  

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
#define N 5000 + 10
using namespace std;
set<int>s1,s2;
struct area
{
int l,r;
int id;
};
int ansx[N],ansy[N];
area x[N],y[N];
bool cmp(area a,area b)
{
return a.r<b.r;
}
int main()
{
int i,n;
int x1,x2,y1,y2;
while(~scanf("%d" ,&n) && n)
{
s1.clear();
s2.clear();
for(i=1;i<=n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x[i].l=x1;x[i].r=x2;
y[i].l=y1;y[i].r=y2;
x[i].id=y[i].id=i;
s1.insert(i);
s2.insert(i);
}
s1.insert(10000000);
s2.insert(10000000);
sort(x+1,x+n+1,cmp);
sort(y+1,y+n+1,cmp);
int flag=0;
for(i=1;i<=n&&!flag;i++)
{
int tmpx=*s1.lower_bound(x[i].l);
if(tmpx>x[i].r)
flag=1;
ansx[x[i].id]=tmpx;
s1.erase(tmpx);
int tmpy=*s2.lower_bound(y[i].l);
if(tmpy>y[i].r)
flag=1;
ansy[y[i].id]=tmpy;
s2.erase(tmpy);
}
if(flag)
{
printf("IMPOSSIBLE ");
continue;
}
for(i = 1 ;i <= n ;i ++)
printf("%d %d " ,ansx[i] ,ansy[i]);
}
}
原文地址:https://www.cnblogs.com/137033036-wjl/p/4960453.html