这道题真是WA得我心力交瘁,好讨厌的感觉啊!

简直木有写题解的心情了

题意:

n×n的棋盘里,放置n个车,使得任意两车不同行且不同列,且第i个车必须放在给定的第i个矩形范围内。输出一种方案,即每个车的坐标,无解的话则输出“IMPOSSIBLE”

行和列是独立的,所以可以分开处理,将二维的转化成了一维区间上的取点问题:

有一个长度为n的区间,还有n个小区间,求一种方案,在每个小区间的范围取一个点,是的大区间上每个单位1的区间里都有点。

开始写的贪心是错误的:

按区间的左端点从小到大排序,然后右端点从小到大二级排序。

这里有个反例:

比如按这种方式排序后的区间是:[1, 3] [1, 3] [2, 2]

那么第一第二个点会放在前两个[1, 3]里面,而第三个点就放不下了。

但是显然这种情况是有合法方案的。

正确的贪心方式:

先对区间的右端点从小到大排序,然后左端点从大到小二级排序(满足区间短的先选)。

从区间的角度考虑:

然后对于每个区间,在它所覆盖的范围从左到右遍历,如果没有放点,就放进去。如果遍历完整个区间都没有点能放,就说明不存在合法方案。

从点考虑的话,我又WA掉了。。=_=||

将区间排序后,从第一个点开始,找到第一个能放进去的区间就放下。

下面是AC的代码君:

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
struct Node
{
int x1, x2, y1, y2;
int x, y;
int order;
}a[maxn];
int n;
bool vis[maxn]; bool cmp1(Node a, Node b)
{
return a.x2 < b.x2 || (a.x2 == b.x2 && a.x1 > b.x1);
} bool cmp2(Node a, Node b)
{
return a.y2 < b.y2 || (a.y2 == b.y2 && a.y1 > b.y1);
} bool cmp3(Node a, Node b)
{
return a.order < b.order;
} int main(void)
{
#ifdef LOCAL
freopen("11134in.txt", "r", stdin);
#endif while(scanf("%d", &n) == && n)
{
for(int i = ; i < n; ++i)
{
scanf("%d%d%d%d", &a[i].x1, &a[i].y1, &a[i].x2, &a[i].y2);
a[i].order = i;
} memset(vis, false, sizeof(vis));
flag = true;
sort(a, a + n, cmp1);
for(int i = ; i < n; ++i)
{
for(j = a[i].x1; j <= a[i].x2; ++j)
{
if(!vis[j])
{
vis[j] = true;
a[i].x = j;
break;
}
}
if(j > a[i].x2)
{
flag = false;
break;
}
} if(flag)
{
memset(vis, false, sizeof(vis));
sort(a, a + n, cmp2);
for(int i = ; i < n; ++i)
{
for(j = a[i].y1; j <= a[i].y2; ++j)
{
if(!vis[j])
{
vis[j] = true;
a[i].y = j;
break;
}
if(j > a[i].y2)
{
flag = false;
break;
}
}
}
} if(flag)
{
sort(a, a + n, cmp3);
for(int i = ; i < n; ++i) printf("%d %d\n", a[i].x, a[i].y);
}
else
puts("IMPOSSIBLE");
} return ;
}

代码君

UVa 11134 (区间上的贪心) Fabled Rooks的更多相关文章

  1. nyoj891(区间上的贪心)

    题目意思: 给一些闭区间,求最少须要多少点,使得每一个区间至少一个点. http://acm.nyist.net/JudgeOnline/problem.php?pid=891 例子输入 4 1 5 ...

  2. 紫书 例题8-4 UVa 11134(问题分解 + 贪心)

     这道题目可以把问题分解, 因为x坐标和y坐标的答案之间没有联系, 所以可以单独求两个坐标的答案 我一开始想的是按照左区间从小到大, 相同的时候从右区间从小到大排序, 然后WA 去uDebug找了数据 ...

  3. 01_传说中的车(Fabled Rooks UVa 11134 贪心问题)

    问题来源:刘汝佳<算法竞赛入门经典--训练指南> P81: 问题描述:你的任务是在n*n(1<=n<=5000)的棋盘上放n辆车,使得任意两辆车不相互攻击,且第i辆车在一个给定 ...

  4. 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 ...

  5. UVa 11134 Fabled Rooks(贪心)

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

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

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

  7. UVA 11134 Fabled Rooks 贪心

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

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

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

  9. 贪心 uvaoj 11134 Fabled Rooks

    Problem F: Fabled Rooks We would like to place n rooks, 1 ≤ n ≤ 5000, on a n×n board subject to the ...

随机推荐

  1. myeclipse 10的破解以及运行run.bat错误或者双击立即消失的问题

    安装包下载: ed2k://|file|[myeclipse.10.0.更新发布].myeclipse-10.0-offline-installer-windows.exe|947752488|73b ...

  2. acdream1116 Gao the string!(扩展KMP)

    今天是字符串填坑的一天,首先填的第一个坑是扩展KMP.总结一下KMP和扩展KMP的区别. 在这里s是主串,t是模式串. KMP可以求出的是以s[i]为结尾的串和 t前缀匹配的最长的长度.假如这个长度是 ...

  3. POJ 1845 Sumdiv (求某个数的所有正因子的和)

    题意: 求A^B的所有正因子的和,最后模9901的结果. 思路: 若对一个数n进行素数分解,n=p1^a1*p2^a2*p3^a3*...*pk^ak那么n的所有正因子之和sum=(1+p1+...+ ...

  4. iOS应用间的跳转和传值

    在第一个应用程序中info.plist设置 URL Identifier: 该字符串是你自定义的 URL scheme 的名字 注意: URL Schemes 是一个数组,允许应用定义多个 URL s ...

  5. opengl还有地方要写

    今天先到这吧... 别忘记了,明天补上! 2014.3.10

  6. oracle连接数据

    1.源代码 string connString = "User ID=scott;Password=yanhong;Data Source=(DESCRIPTION = (ADDRESS_L ...

  7. oci.dll文件是用来干嘛的? 如果没有安装ORACLE客户端提示oci.dll未加载

    oracle数据库开发编程中,没有找到oci.dll,一般是系统的 path 设置有问题, 查找oci.dll, 然后加入到系统路径.oci.dll 可下载解压到系统盘的system32目录下.然后打 ...

  8. lintcode:打劫房屋II

    题目 打劫房屋II 在上次打劫完一条街道之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子围成了一个圈,这就意味着第一间房子和最后一间房子是挨着的.每个房子都存放着特定金额的钱.你面临的唯一约 ...

  9. Android 基于Socket的聊天室(一)

    Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信. Client A ...

  10. linux下修改tomcat的默认目录

    1.修改tomcat的默认目录.它的默认目录是webapps/ROOT,对应的conf目录下的server.xml里的内容是: 1.修改tomcat的默认目录.它的默认目录是webapps/ROOT, ...