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个不同的整数,使得第 ...
随机推荐
- 使用EasyUI的插件前需要引入的文件
一.使用EasyUI的插件需要引入一些文件 1.引入相关文件 easyui.css: easyUi的样式文件 icon.css:easyUI的图标样式文件 easyui.min.js:easyUi的类 ...
- Javascript中void操作符
Javascript中void是一个操作符,该操作符指定要计算一个表达式但是不返回值. void操作符用法格式如下:1.javascript:void (expression)2.javascript ...
- AutoMapper映射ExpressionTree
问题描述 项目中使用AutoMapper进行VO&DTO&Entity的互相映射,但是默认Map方法不支持Expression的转换.如 Expression<Func<E ...
- SharePoint 2013 新功能探索 之 标注控件
SharePoint 2013 引入了新的UI,同时也跟进了网络潮流,把应用最广泛的标注控件也引入到了SharePoint,先看两个应用 以上是两个开发当中经常会用到,下面就介绍一下如何开发相同 ...
- GP的使用心得
在ArcEngine时,GP无疑是GIS开发者的神器.自ArcEngine9.2开始新增一个程序集ESRI.ArcGIS.Geoprocessor,它能调用包含扩展模块在内的所有Geoprocessi ...
- [Java] JDK 系统环境变量设置 bat
@echo off set regpath=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environmen ...
- 学习Android,最简单的按钮提示文本信息
最近都在看Android系统架构跟四大组件,刚开始自己看书看网络资料,简直就是一脸懵,今天在这里对初学者,或者自学的同学,可以跟着我来学习,Android 编码一个按钮出发事件的小案例: 当然,在此之 ...
- IOS 应用跳转 (IOS9白名单)
跳转到指定app的实现 IOS中应用的跳转是通过URL实现的,因此在实现应用跳转之前我们要设置一下对应的URL. 图一(寻找配置软件的URL) 图二(具体配置选项) 注意: 如果IOS版本为IOS9 ...
- UVa 106 - Fermat vs Pythagoras(数论题目)
题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...
- Monyer's Game 6~10关过关方法
从Monyer's Game开通到现在,已经有50多人通关了.其中绝大部分人,不管是自己独立完成也好,参考别人也罢,都是自己一步一步过去的.像陆羽兄弟甚至已经为游戏做好了整个通关的教程,在此Monye ...