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辆车的所能在的矩阵的范 ...
随机推荐
- PYTHON-进阶-装饰器小结,转载
本文转载自:http://www.wklken.me/posts/2012/10/27/python-base-decorator.html 基本概念 具体概念自己google 装饰器是一个很著名的设 ...
- NTP时间服务器搭建
系统时区设置::: 查看当前时区# date -R修改系统时区# timeconfig 或# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtim ...
- 富文本编辑器-UEditor
官方网址:http://ueditor.baidu.com/website/index.html 下载地址:http://ueditor.baidu.com/website/download.html ...
- Android中app卡顿原因分析示例
在知乎回答了一个“为什么微博的app在iPhone比Android上流畅”的问题.后面部分是一个典型的动画卡顿的性能分析过程,因此帖在这里.有编程问题可以在这里交流.知乎链接. =========== ...
- python中使用Opencv进行人脸识别
上一节讲到人脸检测,现在讲一下人脸识别.具体是通过程序采集图像并进行训练,并且基于这些训练的图像对人脸进行动态识别. 人脸识别前所需要的人脸库可以通过两种方式获得:1.自己从视频获取图像 2.从人 ...
- mysql物理备份
原本以为直接将data文件夹下每个数据库对应的文件夹拷贝到新的MySQL的data文件夹就可以了,其实不然. 这样做有几个问题: 1.如果是用了引擎的表,还需要复制ibdata文件,并且frm文件所在 ...
- 真验货客户尾缀sql
'; --select * from TB_ADDBOMWG_LOG; --SELECT * FROM TB_MAN_ROUTING_QM; SELECT * FROM IN_ITEM WHERE I ...
- keras—神经网络CNN—MNIST手写数字识别
from keras.datasets import mnist from keras.utils import np_utils from plot_image_1 import plot_imag ...
- iOS - xcode - label 字体自动根据宽高 显示完全
1. label 左右约束要给. 2.代码实现label.adjustsFontSizeToFitWidth = YES
- 4-计算九位数以内各个位数字和为s的种类
/*假设我们当前要求的是100以内各位数之和和等于s的数有多少个,可以想到就是10以内各位数之和等于s的数的个数再加上10到100内的各位数之和等于s的个数.令dp[i][j]就代表10的j次方内各位 ...