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中的水题.考虑到其点的 ...
随机推荐
- Python学习笔记——Day4
字符串操作 string典型的内置方法: count() center() startswith() find() format() lower() upper() strip() replace() ...
- SpringMVC学习系列(4) 之 数据绑定-1
在系列(3)中我们介绍了请求是如何映射到一个action上的,下一步当然是如何获取到请求中的数据,这就引出了本篇所要讲的内容—数据绑定. 首先看一下都有哪些绑定数据的注解: 1.@RequestPar ...
- HTML标签_01
<!DOCTYPE html> <html> <body> <h1>我的第一个标题</h1> <p>我的第一个段落.</p ...
- Access使用参数化UPDATE数据时,数据无法更新的问题
今天update access数据库时,使用了参数化的方式,结果不报错,但是数据也没有更新.经过google发现access使用参数化时,参数位置必须和赋值顺序相同才行,否则更新时就会出现数据无法更新 ...
- 1.注册或登录页面设计:UILabel,UIButton,UITextField
学习iOS开发已经有一段时日了,之前一直没有系统的对iOS开发的相关知识进行归纳总结,导致很多知识点云里雾里在脑子里形不成iOS开发的思想,现将自己在学习过程中遇到的一些知识进行总结,希望能对iOS初 ...
- [IIS]IIS扫盲(八)
iis - IIS之FTP服务器 一.建立你的FTP站点 第一个FTP站点(即“默认FTP站点”)的设置方法和更多FTP站点的建立方法请参照前文Web服务器中相关操作执行.需要注意的是,如果你要用一 ...
- Monty Hall Problem的一个图解,感觉不错
从Coursera.org上的台大概率课讨论组里拿来的 如果不转换,选中汽车的概率是1/3,非常显然. 但转换后选中汽车的概率变成2/3就有点反直觉了,并不是太容易想明白. 因为转换其实有4种:汽车- ...
- VBA_Excel_教程:分枝循环结构
Sub 分枝() tmp = Cells(, ).Value '变量不用定义,当前写代码的Sheet Debug.Print tmp " Then Debug.Print "A&q ...
- MVC 项目中为什么会有两个web.config
我们对MVC 并不陌生, 在创建MVC项目时,总会发现,在工程目录 中有两个 web.config 文件,一个是在工程的根目录下,一是在 views 下,两个web.config 中的内容也不尽相同, ...
- WM_CLOSE WM_DESTROY WM_QUIT的区别
WM_CLOSE:关闭应用程序窗口 WM_DESTROY:关闭应用程序 WM_QUIT:关闭消息循环