UVa 11134 Fabled Rooks (贪心+问题分解)
题意:在一个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 (贪心+问题分解)的更多相关文章
- 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——[问题分解、贪心法]
We would like to place n rooks, ≤ n ≤ , on a n × n board subject to the following restrictions • The ...
- uva 11134 - Fabled Rooks(问题转换+优先队列)
题目链接:uva 11134 - Fabled Rooks 题目大意:给出n,表示要在n*n的矩阵上放置n个车,并且保证第i辆车在第i个区间上,每个区间给出左上角和右小角的坐标.另要求任意两个车之间不 ...
- UVA - 11134 Fabled Rooks问题分解,贪心
题目:点击打开题目链接 思路:为了满足所有的车不能相互攻击,就要保证所有的车不同行不同列,于是可以发现,行与列是无关的,因此题目可以拆解为两个一维问题,即在区间[1-n]之间选择n个不同的整数,使得第 ...
- 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 ...
- UVa 11134 - Fabled Rooks 优先队列,贪心 难度: 0
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- UVA 11134 Fabled Rooks(贪心的妙用+memset误用警示)
题目链接: https://cn.vjudge.net/problem/UVA-11134 /* 问题 输入棋盘的规模和车的数量n(1=<n<=5000),接着输入n辆车的所能在的矩阵的范 ...
随机推荐
- 修改默认的inout输入框背景颜色
https://www.cnblogs.com/beileixinqing/p/6119690.html
- centos升级python2.7
http://meiyitianabc.blog.163.com/blog/static/10502212720133192489840/
- 搭建turbine时 hystrix MaxConcurrentConnections reached 异常
2017-03-28 10:04:47.438 ERROR 1035 --- [InstanceMonitor] c.n.t.monitor.instance.InstanceMonitor : Co ...
- log4j2搭建记录
今天新建了一个项目,自己弄的小玩意,想要做的正式点,就想引入日志.就想到了log4j2,经过几个小时的努力,还真的可以用了,下面就记录一下我是怎么做的. 下面是总的结构: 下面是MAVEN依赖: &l ...
- one by one 项目 part 6
package Controllerservlet; import java.io.IOException; import java.io.PrintWriter; import java.util. ...
- pre换行段落间距
<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"& ...
- 第五章 二叉树(e2)中序遍历
- python 的时间与日期
显示当前日期: import time print time.strftime('%Y-%m-%d %A %X %Z',time.localtime(time.time())) 或者 你也可以用: p ...
- TZOJ 3533 黑白图像(广搜)
描述 输入一个n*n的黑白图像(1表示黑色,0表示白色),任务是统计其中八连块的个数.如果两个黑格子有公共边或者公共顶点,就说它们属于同一个八连块.如图所示的图形有3个八连块. 输入 第1行输入一个正 ...
- 【校招面试 之 C/C++】第8题 C++中的静态绑定与动态绑定
转自:https://blog.csdn.net/chgaowei/article/details/6427731 做了部分修改 为了支持c++的多态性,才用了动态绑定和静态绑定.理解他们的区别有 ...