uva 11134 fabled rooks (贪心)——yhx
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的更多相关文章
- 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 ...
- UVA 11134 Fabled Rooks 贪心
题目链接:UVA - 11134 题意描述:在一个n*n(1<=n<=5000)的棋盘上放置n个车,每个车都只能在给定的一个矩形里放置,使其n个车两两不在同一行和同一列,判断并给出解决方案 ...
- UVA 11134 - Fabled Rooks(贪心+优先队列)
We would like to place n rooks, 1 ≤ n ≤ 5000, on a n×n board subject to the following restrict ...
- uva 11134 - Fabled Rooks(问题转换+优先队列)
题目链接:uva 11134 - Fabled Rooks 题目大意:给出n,表示要在n*n的矩阵上放置n个车,并且保证第i辆车在第i个区间上,每个区间给出左上角和右小角的坐标.另要求任意两个车之间不 ...
- UVa 11134 - Fabled Rooks 优先队列,贪心 难度: 0
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- UVa 11134 Fabled Rooks(贪心)
题目链接 题意 在n*n的棋盘上的n个指定区间上各放1个'车’ , 使他们相互不攻击(不在同行或同列),输出一种可能的方法. 分析 每行每列都必须放车,把行列分开看,若行和列同时有解,则问题有解. ...
- UVA 11134 Fabled Rooks(贪心的妙用+memset误用警示)
题目链接: https://cn.vjudge.net/problem/UVA-11134 /* 问题 输入棋盘的规模和车的数量n(1=<n<=5000),接着输入n辆车的所能在的矩阵的范 ...
- UVa 11134 Fabled Rooks (贪心+问题分解)
题意:在一个n*n的棋盘上放n个车,让它们不互相攻击,并且第i辆车在给定的小矩形内. 析:说实话,一看这个题真是没思路,后来看了分析,原来这个列和行是没有任何关系的,我们可以分开看, 把它变成两个一维 ...
- UVA - 11134 Fabled Rooks问题分解,贪心
题目:点击打开题目链接 思路:为了满足所有的车不能相互攻击,就要保证所有的车不同行不同列,于是可以发现,行与列是无关的,因此题目可以拆解为两个一维问题,即在区间[1-n]之间选择n个不同的整数,使得第 ...
随机推荐
- How to create water Ripple effect using HTML5 canvas
https://www.script-tutorials.com/how-to-create-water-drops-effect-using-html5-canvas/ https://www.sc ...
- Javaweb上下文监听者ServletContextListener
一个监听类,不是一个servlet或JSP,它能监听ServletContext一生中的两个关键事件:初始化(创建)和撤销.这个类实现了javax.servlet.ServletContextList ...
- 利用jquery实现网页禁止鼠标右键、禁止复制
很多时候,网站的内容辛苦写法被轻松复制,为了不让自己的劳动成果外流,可以利用禁止鼠标右键等方式保护自己的原创内容! 方式1:禁止鼠标右键操作 <script src="http://l ...
- S2 易买网总结
易买网项目总结 --指导老师:原玉明 不知不觉,又到了S2结业的时间了,S1的项目KTV项目还历历在目.一路走来,感觉时间过的好快,我们离就业也越来越近... 展示: 1.主页面(首页) 01.商品分 ...
- PowerBuilder反编译
最近需要了解某个PowerBuilder程序如何工作的,这已经是某个时代的产物了.除了EXE之外,还有一些PBD文件.PBD文件是PowerBuilder动态库,作为本地DLL的一个替 ...
- jQuery实现图片伦播效果(淡入淡出+左右切换)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- CSS中background背景色的作用范围
在div中设置背景色:当border宽度很大时就要考虑一个问题,那就是背景的作用范围,是包括边框呢?还是不包括呢?很明显,又到浏览器产生分歧的时候了. 在IE中背景色的作用范围为:content+pa ...
- iscroll性能
iscroll是比较耗性能的,在iPhone和性能比较好的机是比较流畅的,在性能低的手机就会出现卡的情况.所以如果不想出现这种情况,只有不使用iscroll,囧.
- 0728关于html的几个基础知识点
1.文本的格式化. 文本的格式包括粗体,斜体等.<b></b>定义粗体,<i>定义斜体</i>,<del></del> 定义删除 ...
- JavaScript hasOwnProperty() 函数详解
hasOwnProperty()函数用于指示一个对象自身(不包括原型链)是否具有指定名称的属性.如果有,返回true,否则返回false. 该方法属于Object对象,由于所有的对象都"继承 ...