题意:在一个n*n的棋盘上放n个车,让它们不互相攻击,并且第i辆车在给定的小矩形内。

析:说实话,一看这个题真是没思路,后来看了分析,原来这个列和行是没有任何关系的,我们可以分开看,

把它变成两个一维问题,也就是说,我们可以把行看成是1-n,然后把x1-x2看成小区间,这样的话,

是不是就感觉简单的了,还有好几坑,被坑的惨惨的。

首先对行排序,按照每个右端点排,然后扫一遍,去找左端点,找到就立马选上(贪心),并且是一定满足的,

如果找不到,就退出,说明没有解。同理列也是这样。

后来看了Rujia Liu的代码,那叫一个精简啊,连结构体都没用,真是大神啊。

我的代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath> using namespace std;
const int maxn = 5000 + 10;
struct node{
int x1, x2, y1, y2;
int x, y, id;
bool usedx, usedy;
};
node a[maxn]; bool cmp1(const node &p, const node &q){ return p.x2 < q.x2; } bool cmp2(const node &p, const node &q){ return p.y2 < q.y2; } bool cmp3(const node &p, const node &q){ return p.id < q.id; } int main(){
int n;
while(scanf("%d", &n) && n){
for(int i = 0; i < n; ++i){
scanf("%d %d %d %d", &a[i].x1, &a[i].y1, &a[i].x2, &a[i].y2);
a[i].usedx = a[i].usedy = false;
a[i].id = i;
} sort(a, a+n, cmp1);
bool ok;
for(int i = 0; i < n; ++i){
ok = false;
for(int j = 0; j < n; ++j){
if(!a[j].usedx && a[j].x1 <= i+1){
if(a[j].x2 <= i) break;
a[j].x = i+1;
a[j].usedx = true;
ok = true;
break;
}
}
if(!ok) break;
}
if(!ok){ printf("IMPOSSIBLE\n"); continue; } // puts("++++");
sort(a, a+n, cmp2);
for(int i = 0; i < n; ++i){
ok = false;
for(int j = 0; j < n; ++j){
if(!a[j].usedy && a[j].y1 <= i+1){
if(a[j].y2 <= i) break;
a[j].y = i+1;
a[j].usedy = true;
ok = true;
break;
}
}
if(!ok) break;
}
if(!ok){ printf("IMPOSSIBLE\n"); continue; } sort(a, a+n, cmp3);
for(int i = 0; i < n; ++i)
printf("%d %d\n", a[i].x, a[i].y);
}
return 0;
}

下面是Rujai Liu的代码真是膜拜啊:

#include<cstdio>
#include<cstring>
#include <algorithm>
using namespace std; bool solve(int *a, int *b, int *c, int n) {
fill(c, c+n, -1);
for(int col = 1; col <= n; col++) {
int rook = -1, minb = n+1;
for(int i = 0; i < n; i++)
if(c[i] < 0 && b[i] < minb && col >= a[i]) { rook = i; minb = b[i]; }
if(rook < 0 || col > minb) return false;
c[rook] = col;
}
return true;
} const int maxn = 5000 + 5;
int n, x1[maxn], yy1[maxn], x2[maxn], y2[maxn], x[maxn], y[maxn]; int main() {
while(scanf("%d", &n) == 1 && n) {
for (int i = 0; i < n; i++)
scanf("%d%d%d%d", &x1[i], &yy1[i], &x2[i], &y2[i]);
if(solve(x1, x2, x, n) && solve(yy1, y2, y, n))
for (int i = 0; i < n; i++) printf("%d %d\n", x[i], y[i]);
else
printf("IMPOSSIBLE\n");
}
return 0;
}

UVa 11134 Fabled Rooks (贪心+问题分解)的更多相关文章

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

  2. UVA 11134 Fabled Rooks 贪心

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

  3. UVA 11134 - Fabled Rooks(贪心+优先队列)

    We would like to place  n  rooks, 1 ≤  n  ≤ 5000, on a  n×n  board subject to the following restrict ...

  4. UVa 11134 - Fabled Rooks——[问题分解、贪心法]

    We would like to place n rooks, ≤ n ≤ , on a n × n board subject to the following restrictions • The ...

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

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

  6. UVA - 11134 Fabled Rooks问题分解,贪心

    题目:点击打开题目链接 思路:为了满足所有的车不能相互攻击,就要保证所有的车不同行不同列,于是可以发现,行与列是无关的,因此题目可以拆解为两个一维问题,即在区间[1-n]之间选择n个不同的整数,使得第 ...

  7. uva 11134 fabled rooks (贪心)——yhx

    We would like to place n rooks, 1 n 5000, on a n nboard subject to the following restrictions• The i ...

  8. UVa 11134 - Fabled Rooks 优先队列,贪心 难度: 0

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  9. UVA 11134 Fabled Rooks(贪心的妙用+memset误用警示)

    题目链接: https://cn.vjudge.net/problem/UVA-11134 /* 问题 输入棋盘的规模和车的数量n(1=<n<=5000),接着输入n辆车的所能在的矩阵的范 ...

随机推荐

  1. Simple2D-24 Sprite 渲染树

    如果要开发游戏,单单使用 Painter 绘制图片会变得十分复杂.如果使用 Sprite 对象进行显示,可以简单地实现图片的位移.旋转和缩放,结合 Action 对象可以实现复杂的动画效果.最重要的是 ...

  2. zookeeper集群搭建 windows

    本次zk测试部署版本为3.4.6版本,下载地址http://mirrors.cnnic.cn/apache/zookeeper/ 限于服务器个数有限本次测试了两种情况 1.单节点方式:部署在一台服务器 ...

  3. tomcat manager

    在点击tomcat manager的时候提示以下内容: You are not authorized to view this page. By default the Host Manager is ...

  4. referer null

    Referer表示超链接源的URL!你想看到实验效果,要从a-->(能过<a href="b.jsp")b页面,然后在B里可以取得Refere参数! String ur ...

  5. 通过Chrome的inspect对手机webview进行调试

    使用chrome的inspect可以对手机上的webview进行调试,因为真机没有什么比较好的调试工具,而chrome提供了这一个工具可以比较方便的查看真机上的元素,以及进行调试. 其实我对webvi ...

  6. toString方法的用法

    public class JLDtoS {   public static void main(String[]args)   {    long a=123;    Long aa=new Long ...

  7. php页面的基本语法

    概述: 1. PHP 脚本在服务器上执行,然后将纯 HTML 结果发送回浏览器. 2. PHP 脚本以 <?php 开始,以 ?> 结束,可以放到文档中的任何位置. 3. 当 PHP 解析 ...

  8. JAVA 系统变量之System.getenv()和System.getProperty() 用法

    Java提供了System类的静态方法getenv()和getProperty()用于返回系统相关的变量与属性,getenv方法返回的变量大多于系统相关,getProperty方法返回的变量大多与ja ...

  9. swift UITextfield 添加点击方法 - 简单实现

    1. 真正在任何系统上都有效的方法 1./// 城市选择 private lazy var cityTextfield:UITextField = { let tf = UITextField() t ...

  10. [ERROR] Failed to contact master at [localhost:11311]. Retrying...

    [ERROR] [1446531999.044935824]: [registerPublisher] Failed to contact master at [localhost:11311]. R ...