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个不同的整数,使得第 ...
随机推荐
- 与众不同 windows phone (52) - 8.1 新增控件: AutoSuggestBox, ListView, GridView, SemanticZoom
[源码下载] 与众不同 windows phone (52) - 8.1 新增控件: AutoSuggestBox, ListView, GridView, SemanticZoom 作者:webab ...
- IBatis 配置一对多
-------说明-------- IBatis 版本2.0 配置一对多 namespace = testDao ------------------ /** *班级的resultMap *Class ...
- 【背景建模】PBAS
Pixel-Based Adaptive Segmenter(PBAS)检测算法,是基于像素的无参数模型,该算法结合了SACON和VIBE两个算法的优势,并在这两个算法的基础上改进而来,SACON和V ...
- java获取class所在jar
在类库的开发过程中,有些时候为了self-contain的原因,我们希望所有的资源都打包在jar中,但是有些工具好像无法支持从classpasth直接获取比如velocity的模板合并,此时我们就知道 ...
- jquery TypeError: 'undefined' is not a function (evaluating 'elem.nodeName.toLowerCase()') [jquery.js:1904]错误原因
今天,某个环境报了个js错误,TypeError: 'undefined' is not a function (evaluating 'elem.nodeName.toLowerCase()') [ ...
- CentOS下apache绑定域名
本文主要介绍在CentOS下apache绑定域名以及apache绑定多个域名,首先要找到apache的配置文件httpd.conf的位置.CentOS操作系统一般在 /etc/httpd/conf 下 ...
- andriod ==和equals
== 用于数字 equals用于字符
- C++pair类型
标准库类型--pair类型定义在utility头文件中定义 本文地址:http://www.cnblogs.com/archimedes/p/cpp-pair.html,转载请注明源地址. 1.pai ...
- iOS-多线程--(pthread/NSThread/GCD/NSOperation)--总结
零.线程的注意点(掌握) .不要同时开太多的线程(~3条线程即可,不要超过5条) .线程概念 > 主线程 : UI线程,显示.刷新UI界面,处理UI控件的事件 > 子线程 : 后台线程,异 ...
- OC语言-02-OC语言-基础知识
一.基础语法 1> OC语言和C语言 C语言是面向过程的语言,OC语言是面向对象的语言 OC语言继承了C语言,并增加了面向对象的思想 以下内容只介绍OC语言与C语言的不同之处 2> 关键字 ...