题意:在一个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. python-淘宝信息定向爬取

    S是类似产品页数  bcoffset直流偏移. 有人在将偏移量:http://www.cnblogs.com/defineconst/p/6185396.html item.taobao.com/it ...

  2. 不用登陆密码也能进路由器,适用于TP、磊科、腾达

    结合wooyun提供的腾达COOKIE漏洞,结合自己的经验,成功进入腾达路由器破解其登陆密码和无线密码. 教程开始: 所用工具:WebCruiser 输入路由网关,出现登陆界面. 选择:COOKIE  ...

  3. 吴裕雄 python神经网络 水果图片识别(2)

    import osimport numpy as npimport matplotlib.pyplot as pltfrom skimage import color,data,transform,i ...

  4. shell 一次移动很多个命名相似的文件

    文件夹下面有很多类似下面命名的文件 aaaaaa01bbb aaaaaa01cc aaaaaa01dd aaaaaa02bbb aaaaaa02cc 要把 aaaaaa01 的文件移走 用 mv  / ...

  5. Python在pycharm中编程时应该注意的问题汇总

    1.缩进问题 在 pycharm 中点击 enter 自动进行了换行缩进,此时应该注意:比如 if   else  语句,后面跟着打印输出 print 的时候,一定注意是要if语句下的输出还是else ...

  6. https 证书传递、验证和数据加密、解密过程解析

    我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取.所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议. HTTPS简介 HTTPS其实是有两部分组成:HTTP + SSL ...

  7. 各种id生成策略

    package com.taotao.utils; import java.util.Random; /** * 各种id生成策略 */ public class IDUtils { /** * 图片 ...

  8. Loadrunner进行参数化

    Loadrunner进行参数化 Loadrunner中进行参数化,这里有三种方法. 对需要多次使用的变量进行参数化,比如登录信息的用户名和密码,首先需要选中需要参数化的值,然后右键选择Replace ...

  9. 使用spring-data-JPA调用存储过程

    第一种情况,对于只有一个或没有返回值的存储过程,使用如下方式调用: @Entity @NamedStoredProcedureQuery(name = "pro1", proced ...

  10. 阿里云SSL证书tomcat配置

    1. SSL证书申请 登录阿里云控制台,查看购买域名中有SSL证书的申请,ssl证书申请中有单域名的申请,配置要申请的域名信息(注意:一个域名下,一次只能添加一个证书,最多申请3个免费证书用于测试), ...