POJ 1873 - The Fortified Forest 凸包 + 搜索 模板
通过这道题发现了原来写凸包的一些不注意之处和一些错误..有些错误很要命..
这题 N = 15
1 << 15 = 32768 直接枚举完全可行
卡在异常情况判断上很久,只有 顶点数 >= 2,即 n >= 3 时凸包才有意义
顶点数为 1 时,tmp = - 1 要做特殊判断。
总结了一下凸包模板
//template Convex Hull
friend bool operator < (const point &p1, const point &p2){
return (p1.x < p2.x)||(p1.x == p2.x)&&(p1.y < p2.y);
}
void BBS(point p[], int n){
for (int i = 0; i < n; i++){
for (int j = 0; j < i; j++){
if (p[i] < p[j])
swap(p[i], p[j]);
}
}
}
void Convex_Hull(point p[], int n){
BBS(p, n); //先按横坐标升序排序,保证p[0]在凸包上
cur = 0;
while (1){
int tmp = - 1;
for (int i = 0; i < n; i++){
if (i != cur){
if (!(tmp + 1)||(((p[cur] >> p[i]) ^ (p[cur] >> p[tmp])) > 0))
tmp = i;
}
}
if (tmp + 1){
//找到凸包上的点p[tmp]
}
if (!tmp||!(tmp + 1)) break;
cur = tmp;
}
}
POJ1873.cpp
//POJ1873
//DFS + 凸包
//注意规避异常状况
//if (tmp + 1)
// d += (p[cur] >> p[tmp]).norm();
//写代码不认真,出现了许多错误,务必注意
//AC 2016-10-14 #include "cstdio"
#include "cstdlib"
#include "cmath"
#include "iostream"
#define MAXN 20 double sqr(double x){
return x * x;
} struct point{
int x, y, v, l;
bool cut;
point(){}
point(int X, int Y): x(X), y(Y), cut(0){}
friend point operator >> (const point &p1, const point &p2){
return point(p2.x - p1.x, p2.y - p1.y);
}
friend int operator ^ (const point &p1, const point &p2){
return p1.x * p2.y - p1.y * p2.x;
}
double norm(){
return sqrt(sqr(x) + sqr(y));
}
friend bool operator < (const point &p1, const point &p2){
return (p1.x < p2.x)||(p1.x == p2.x)&&(p1.y < p2.y);
}
friend bool operator > (const point &p1, const point &p2){
return (p1.x > p2.x)||(p1.x == p2.x)&&(p1.y > p2.y);
}
}pt[MAXN], p[MAXN], ans[MAXN]; int m0, minval, n, val, len;
double det; void GetPoints(point src[], point dest[], int n, int &m){
m = 0;
for (int i = 0; i < n; i++){
if (!src[i].cut){
dest[m++] = src[i];
}
}
} template <class T>
void swap(T &x, T &y){
T z = x;
x = y;
y = z;
} void BBS(point p[], int n){
for (int i = 0; i < n; i++){
for (int j = 0; j < i; j++){
if (p[i] < p[j])
swap(p[i], p[j]);
}
}
} void dfs(int x){
if (!(x + 1)){
int cur = 0, m, l = len;
double d = 0, v = val;
GetPoints(pt, p, n, m);
BBS(p, m);
for (int i = 0; i < m; i++){
v -= p[i].v;
l -= p[i].l;
}
while (1){
int tmp = - 1;
for (int i = 0; i < m; i++){
if (i != cur){
if (!(tmp + 1)||(((p[cur] >> p[i]) ^ (p[cur] >> p[tmp])) > 0))
tmp = i;
}
}
if (tmp + 1)
d += (p[cur] >> p[tmp]).norm();
if (!tmp||!(tmp + 1)) break;
cur = tmp;
}
if (d > l) return;
if ((v < minval)||(v == minval)&&(m < m0)){
minval = v, det = l - d, m0 = m;
for (int i = 0; i < n; i++)
ans[i] = pt[i];
}
}
else{
pt[x].cut = 0;
dfs(x - 1);
pt[x].cut = 1;
dfs(x - 1);
}
} int main(){
int irr = 0;
freopen("fin.c", "r", stdin);
while(scanf("%d", &n), n){
val = len = 0, irr++, det = 0;
m0 = 0x7f7f7f7f, minval = 0x7f7f7f7f;
for (int i = 0; i < n; i++){
scanf("%d%d%d%d", &pt[i].x, &pt[i].y, &pt[i].v, &pt[i].l);
val += pt[i].v, len += pt[i].l;
}
dfs(n - 1);
if (irr > 1) puts("");
printf("Forest %d\n", irr);
printf("Cut these trees:");
for (int i = 0; i < n; i++){
if (ans[i].cut)
printf(" %d", i + 1);
}
printf("\nExtra wood: %.2f\n", det);
}
}
POJ 1873 - The Fortified Forest 凸包 + 搜索 模板的更多相关文章
- POJ 1873 The Fortified Forest [凸包 枚举]
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6400 Accepted: 1 ...
- POJ 1873 The Fortified Forest 凸包 二进制枚举
n最大15,二进制枚举不会超时.枚举不被砍掉的树,然后求凸包 #include<stdio.h> #include<math.h> #include<algorithm& ...
- 简单几何(凸包+枚举) POJ 1873 The Fortified Forest
题目传送门 题意:砍掉一些树,用它们做成篱笆把剩余的树围起来,问最小价值 分析:数据量不大,考虑状态压缩暴力枚举,求凸包以及计算凸包长度.虽说是水题,毕竟是final,自己状压的最大情况写错了,而且忘 ...
- POJ 1873 The Fortified Forest(凸包)题解
题意:二维平面有一堆点,每个点有价值v和删掉这个点能得到的长度l,问你删掉最少的价值能把剩余点围起来,价值一样求删掉的点最少 思路:n<=15,那么直接遍历2^15,判断每种情况.这里要优化一下 ...
- POJ 1873 The Fortified Forest(枚举+凸包)
Description Once upon a time, in a faraway land, there lived a king. This king owned a small collect ...
- ●POJ 1873 The Fortified Forest
题链: http://poj.org/problem?id=1873 题解: 计算几何,凸包 枚举被砍的树的集合.求出剩下点的凸包.然后判断即可. 代码: #include<cmath> ...
- POJ 1873 The Fortified Forest
题意:是有n棵树,每棵的坐标,价值和长度已知,要砍掉若干根,用他们围住其他树,问损失价值最小的情况下又要长度足够围住其他树,砍掉哪些树.. 思路:先求要砍掉的哪些树,在求剩下的树求凸包,在判是否可行. ...
- poj1873 The Fortified Forest 凸包+枚举 水题
/* poj1873 The Fortified Forest 凸包+枚举 水题 用小树林的木头给小树林围一个围墙 每棵树都有价值 求消耗价值最低的做法,输出被砍伐的树的编号和剩余的木料 若砍伐价值相 ...
- Uva5211/POJ1873 The Fortified Forest 凸包
LINK 题意:给出点集,每个点有个价值v和长度l,问把其中几个点取掉,用这几个点的长度能把剩下的点围住,要求剩下的点价值和最大,拿掉的点最少且剩余长度最长. 思路:1999WF中的水题.考虑到其点的 ...
随机推荐
- 在笔记本电脑开通无线WIFI
1.Windows + R启动运行,输入services.msc进入服务 2.在服务中将Security Center服务从自动启动转为禁止启动 3.在服务中将Windows Firewall的启动类 ...
- Ubuntu中开启MySQL远程访问功能,并将另一个数据库服务器中的数据迁移到新的服务器中
一.开启MyS远程访问功能 1.进入服务器输入netstat -an | grep 3306确认3306是否对外开放,MySQL默认状态下是不对外开放访问功能的.输入以上命令之后如果端口没有被开放就会 ...
- Notepad++配置Python开发环境
1. 安装Python 1 下载 我选择了32位的2.7版本.https://www.python.org/ftp/python/2.7.8/python-2.7.8.msi 2. 安装 安装的时候可 ...
- vb6 获取 http only 的 Cookie
Option Explicit ' No more data is available. ' The data area passed to a system call is too small. P ...
- 【转】关于.net framework4.0以及4.5安装失败,“安装时发生严重错误”……
也不知道管不管用,先记着 今天忽然想装一个vs2010,然后装了好几遍,每次都在安装.net4.0的时候失败.好吧,我自己手动装行么.于是手动去装.net 4.0. 结果在还是返回"安装时发 ...
- 基于SVG的web页面图形绘制API介绍
转自:http://blog.csdn.net/jia20003/article/details/9185449 一:什么是SVG SVG是1999由W3C发布的2D图形描述语言,纯基于XML格式的标 ...
- python中使用xlrd、xlwt操作excel表格详解
python读excel——xlrd 这个过程有几个比较麻烦的问题,比如读取日期.读合并单元格内容.下面先看看基本的操作: 首先读一个excel文件,有两个sheet,测试用第二个sheet,shee ...
- 【MySQL】结构行长度的一些限制
今天被开发提交的DDL变更再次困惑,表中字段较多,希望将已有的两个varchar(4000)字段改为varchar(20000),我想innodb对varchar的存储不就是取前768字节记录当前行空 ...
- 关于block的一些理解
之前一直都是用这别人或者是系统系统封装好的block,用这都挺好,可以访问那些定义了block变量的函数变量在block中使用. 首先总结一个block的用法:1.block有些类似于函数的指针 拥有 ...
- Bootstrap整体架构
大多数Bootstrap的使用者都认为Bootstrap只是提供了CSS组件和JavaScript插件,其实CSS组件和JavaScript插件只是Bootstrap框架的表现形式而已,他们都是构建在 ...