We would like to place n rooks, 1 n 5000, on a n n
board subject to the following restrictions
• The i-th rook can only be placed within the rectan-
gle 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.
Input
The input consists of several test cases. The rst 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 le is terminated with the integer `0' on a line by itself.
Output
Your task is to nd such a placing of rooks that the above conditions are satised and then output n
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.


因为行和列并没有什么关系,所以只要把问题分成两个,如果都能满足,再进行配对即可。

那么问题就变成了在[1,n]上有n个区间,把n个整数恰好不重不漏地分配到每个区间。

很明显用贪心。

 #include<cstdio>
#include<cstring>
struct qj
{
int l,r,num;
}q1,q2;
qj a1[],a2[];
int p1[],p2[],n;
bool xy(qj a,qj b)
{
return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
void st1(int l,int r)
{
int i,j,k;
qj mid=a1[(l+r)/];
i=l;
j=r;
do
{
while (xy(a1[i],mid)) i++;
while (xy(mid,a1[j])) j--;
if (i<=j)
{
p1[a1[i].num]=j;
p1[a1[j].num]=i;
q1=a1[i];
a1[i]=a1[j];
a1[j]=q1;
i++;
j--;
}
}
while (i<=j);
if (l<j) st1(l,j);
if (i<r) st1(i,r);
}
void st2(int l,int r)
{
int i,j,k;
qj mid=a2[(l+r)/];
i=l;
j=r;
do
{
while (xy(a2[i],mid)) i++;
while (xy(mid,a2[j])) j--;
if (i<=j)
{
p2[a2[i].num]=j;
p2[a2[j].num]=i;
q2=a2[i];
a2[i]=a2[j];
a2[j]=q2;
i++;
j--;
}
}
while (i<=j);
if (l<j) st2(l,j);
if (i<r) st2(i,r);
}
int main()
{
int i,j,k,m,p,q,x,y,z;
bool ok;
while (scanf("%d",&n)&&n)
{
for (i=;i<=n;i++)
{
scanf("%d%d%d%d",&q1.l,&q2.l,&q1.r,&q2.r);
p1[i]=p2[i]=q1.num=q2.num=i;
a1[i]=q1;
a2[i]=q2;
}
st1(,n);
st2(,n);
ok=;
for (i=;i<=n;i++)
if (a1[i].l>i||a1[i].r<i||a2[i].l>i||a2[i].r<i)
{
ok=;
break;
}
if (ok)
for (i=;i<=n;i++)
printf("%d %d\n",p1[i],p2[i]);
else
printf("IMPOSSIBLE\n");
}
}

以上是经典的错误答案。(反正我开始就是这么错的)

把区间按左端点排序,第i个区间放整数i。

反例:[1,1],[1,3],[2,2]。照这个贪心思路找不到解。

 #include<cstdio>
#include<cstring>
#define MS(a) memset(a,0,sizeof(a))
int l1[],r1[],l2[],r2[],p1[],p2[];
int main()
{
int i,j,k,m,n,p,q1,q2,x,y,z,min1,min2;
bool ok;
while (scanf("%d",&n)&&n)
{
MS(p1);
MS(p2);
for (i=;i<=n;i++)
scanf("%d%d%d%d",&l1[i],&l2[i],&r1[i],&r2[i]);
ok=;
for (i=;i<=n;i++)
{
q1=q2=-;
min1=min2=;
for (j=;j<=n;j++)
{
if (p1[j]==&&l1[j]<=i&&r1[j]>=i&&r1[j]<min1)
{
q1=j;
min1=r1[j];
}
if (p2[j]==&&l2[j]<=i&&r2[j]>=i&&r2[j]<min2)
{
q2=j;
min2=r2[j];
}
}
if (q1==-||q2==-)
{
ok=;
break;
}
p1[q1]=i;
p2[q2]=i;
}
if (ok)
for (i=;i<=n;i++)
printf("%d %d\n",p1[i],p2[i]);
else
printf("IMPOSSIBLE\n");
}
}

正解:把按顺序枚举区间变成按顺序枚举点。对于每个点,找到它能放的、右端点最小的区间。

若不取这个区间而取另一个右端点更大的区间,会让之后的点选择变少。

uva 11134 fabled rooks (贪心)——yhx的更多相关文章

  1. UVA - 11134 Fabled Rooks[贪心 问题分解]

    UVA - 11134 Fabled Rooks We would like to place n rooks, 1 ≤ n ≤ 5000, on a n × n board subject to t ...

  2. UVA 11134 Fabled Rooks 贪心

    题目链接:UVA - 11134 题意描述:在一个n*n(1<=n<=5000)的棋盘上放置n个车,每个车都只能在给定的一个矩形里放置,使其n个车两两不在同一行和同一列,判断并给出解决方案 ...

  3. UVA 11134 - Fabled Rooks(贪心+优先队列)

    We would like to place  n  rooks, 1 ≤  n  ≤ 5000, on a  n×n  board subject to the following restrict ...

  4. uva 11134 - Fabled Rooks(问题转换+优先队列)

    题目链接:uva 11134 - Fabled Rooks 题目大意:给出n,表示要在n*n的矩阵上放置n个车,并且保证第i辆车在第i个区间上,每个区间给出左上角和右小角的坐标.另要求任意两个车之间不 ...

  5. UVa 11134 - Fabled Rooks 优先队列,贪心 难度: 0

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  6. UVa 11134 Fabled Rooks(贪心)

    题目链接  题意  在n*n的棋盘上的n个指定区间上各放1个'车’ , 使他们相互不攻击(不在同行或同列),输出一种可能的方法. 分析 每行每列都必须放车,把行列分开看,若行和列同时有解,则问题有解. ...

  7. UVA 11134 Fabled Rooks(贪心的妙用+memset误用警示)

    题目链接: https://cn.vjudge.net/problem/UVA-11134 /* 问题 输入棋盘的规模和车的数量n(1=<n<=5000),接着输入n辆车的所能在的矩阵的范 ...

  8. UVa 11134 Fabled Rooks (贪心+问题分解)

    题意:在一个n*n的棋盘上放n个车,让它们不互相攻击,并且第i辆车在给定的小矩形内. 析:说实话,一看这个题真是没思路,后来看了分析,原来这个列和行是没有任何关系的,我们可以分开看, 把它变成两个一维 ...

  9. UVA - 11134 Fabled Rooks问题分解,贪心

    题目:点击打开题目链接 思路:为了满足所有的车不能相互攻击,就要保证所有的车不同行不同列,于是可以发现,行与列是无关的,因此题目可以拆解为两个一维问题,即在区间[1-n]之间选择n个不同的整数,使得第 ...

随机推荐

  1. LeetCode128:Longest Consecutive Sequence

    题目: Given an unsorted array of integers, find the length of the longest consecutive elements sequenc ...

  2. Visual Studio中设置默认VC++路径

    菜单"View" -> "Other Windows" -> "Property Manager" 选择对应的配置并修改即可.

  3. 安装xampp无法设置默认时间的坑

    xampp无法设置默认时间,修改了时间还是无效 [Date] ; Defines the default timezone used by the date functions ; http://ph ...

  4. [git] ignore文件规则失效

    背景 在某次项目,发现已经将.iml规则写进.ignore文件,但是对.iml的修改依然会出现在changelist中. 解决方案 先引用git官网上的描述 gitignore - Specifies ...

  5. 2013 最新的 play web framework 版本 1.2.3 框架学习文档整理

    Play framework框架学习文档 Play framework框架学习文档 1 一.什么是Playframework 3 二.playframework框架的优点 4 三.Play Frame ...

  6. SAP 锁机制

    SAP锁机制一.SAP为什么要设置锁:   1,保持数据的一致性     如果几个用户要访问同样的资源,需要找到一种同步访问的方法去保持数据的一致性.比如说,在航班预订系 统中,需要检查还有没有空座位 ...

  7. SQL语句的简单使用

    首先要先引入libsqlite3.0.tbd框架 DataBaseHandle.h #import <Foundation/Foundation.h> @interface DataBas ...

  8. iOS8以后 UISearchController的用法

    查了不少资料,都不太全,自己查看了apple文档,写了一份代码: 如下(只是界面): 1. 声明属性 @property (nonatomic, strong) UISearchController ...

  9. Swift学习--闭包的简单使用(三)

    一.Swift中闭包的简单使用 override func viewDidLoad() { super.viewDidLoad() /** 闭包和OC中的Block非常相似 OC中的block类似于匿 ...

  10. 我遇到的CocoaPods的问题(也许后期会解决,持续更新)

    在此博客中写下两类关于CocoaPods的问题: 未解决的问题:可以留着以后解决 已经解决的问题:可以备份以后回头再参考解决同样的问题 <已解决的问题> 解决方法是:pod install ...