这道题真是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. Java正则表达式匹配例子

    Java正则表达式匹配例子 package com.ibm.test; import java.util.regex.Matcher; import java.util.regex.Pattern; ...

  2. mysql关联修改SQL及long与datetime类型相互转换

    1.关联修改 #解决思路 UPDATE tb1,tb2 SET tb1.address=tb2.address WHERE tb1.name=tb2.name UPDATE car c,tmpcolo ...

  3. URAL 1517 Freedom of Choice(后缀数组,最长公共字串)

    题目 输出最长公共字串 #define maxn 200010 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; int cmp(int *r,int a,int b, ...

  4. 用C语言代码判别CPU的大小端模式

     Big-endian和little-endian是描述排列存储在计算机内存里的字节序列的术语.       Big-endian是一种大值的一端(序列中更典型值)存在前面(在最小的存储地址)的顺序. ...

  5. POJ 3180

    The Cow Prom Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1132   Accepted: 713 Descr ...

  6. POJ 2070

    #include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("a ...

  7. hdu 3271 SNIBB 数位DP+二分

    思路:dp[i][j]:表示第i位在B进制下数字和. 用二分找第k个数! 代码如下: #include<iostream> #include<stdio.h> #include ...

  8. Java 网络编程(一)

    网络通讯要素 IP地址(InetAddress) 端口号 传输协议 图示: TDP/IP模型 以OSI 7层模型讲解数据的传输 InetAddress   InetAddress类主要表示IP地址. ...

  9. JS初学的一些易错的知识点

    1.  false ,0 , "" ,undefined , null  在Boolean 环境下当成 false: null  在数值环境下当成 0: undefined 在数值 ...

  10. lintcode :First bad version 第一个错误的代码版本

    题目 第一个错误的代码版本 代码库的版本号是从 1 到 n 的整数.某一天,有人提交了错误版本的代码,因此造成自身及之后版本的代码在单元测试中均出错.请找出第一个错误的版本号. 你可以通过 isBad ...