传送门:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2075
已知n*n的棋盘上放置n个车,使得每个车不互相攻击,每个车只能放在某个矩形内
输出一种方案,如果无解输出“IMPOSSIBLE”
对于x,y轴可分开考虑,问题转化为在1~n的区间上放置的问题
贪心,将区间按右端点从小到大排序,当相同时,按左端点排序,每次从当前区间找到第一个未放置的点,标记为放置,如果找不到则无解
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct segment
{
int l,r;
int ans;
int no;
};
int n;
bool f[5005];
segment x[5005],y[5005];
int now;
bool cmp1(const segment a,const segment b)
{
if (a.r<b.r)
{
return 1;
}
if (a.r>b.r)
{
return 0;
}
return a.l<b.l;
}
bool cmp2(const segment a,const segment b)
{
return a.no<b.no;
}
void PRINT()
{
sort(x+1,x+n+1,cmp1);
sort(y+1,y+n+1,cmp1);
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++)
{
x[i].ans=0;
for (int j=x[i].l;j<=x[i].r;j++)
{
if (!f[j])
{
x[i].ans=j;
f[j]=1;
break;
}
}
if (!x[i].ans)
{
printf("IMPOSSIBLE\n");
return;
}
}
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++)
{
y[i].ans=0;
for (int j=y[i].l;j<=y[i].r;j++)
{
if (!f[j])
{
y[i].ans=j;
f[j]=1;
break;
}
}
if (!y[i].ans)
{
printf("IMPOSSIBLE\n");
return;
}
}
sort(x+1,x+n+1,cmp2);
sort(y+1,y+n+1,cmp2);
for (int i=1;i<=n;i++)
{
printf("%d %d\n",x[i].ans,y[i].ans);
}
}
int main()
{
while (1)
{
scanf("%d",&n);
if (!n)
{
break;
}
for (int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&x[i].l,&y[i].l,&x[i].r,&y[i].r);
x[i].no=i;
y[i].no=i;
}
PRINT();
}
return 0;
}