通过这道题发现了原来写凸包的一些不注意之处和一些错误..有些错误很要命..

这题 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 凸包 + 搜索 模板的更多相关文章

  1. POJ 1873 The Fortified Forest [凸包 枚举]

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6400   Accepted: 1 ...

  2. POJ 1873 The Fortified Forest 凸包 二进制枚举

    n最大15,二进制枚举不会超时.枚举不被砍掉的树,然后求凸包 #include<stdio.h> #include<math.h> #include<algorithm& ...

  3. 简单几何(凸包+枚举) POJ 1873 The Fortified Forest

    题目传送门 题意:砍掉一些树,用它们做成篱笆把剩余的树围起来,问最小价值 分析:数据量不大,考虑状态压缩暴力枚举,求凸包以及计算凸包长度.虽说是水题,毕竟是final,自己状压的最大情况写错了,而且忘 ...

  4. POJ 1873 The Fortified Forest(凸包)题解

    题意:二维平面有一堆点,每个点有价值v和删掉这个点能得到的长度l,问你删掉最少的价值能把剩余点围起来,价值一样求删掉的点最少 思路:n<=15,那么直接遍历2^15,判断每种情况.这里要优化一下 ...

  5. POJ 1873 The Fortified Forest(枚举+凸包)

    Description Once upon a time, in a faraway land, there lived a king. This king owned a small collect ...

  6. ●POJ 1873 The Fortified Forest

    题链: http://poj.org/problem?id=1873 题解: 计算几何,凸包 枚举被砍的树的集合.求出剩下点的凸包.然后判断即可. 代码: #include<cmath> ...

  7. POJ 1873 The Fortified Forest

    题意:是有n棵树,每棵的坐标,价值和长度已知,要砍掉若干根,用他们围住其他树,问损失价值最小的情况下又要长度足够围住其他树,砍掉哪些树.. 思路:先求要砍掉的哪些树,在求剩下的树求凸包,在判是否可行. ...

  8. poj1873 The Fortified Forest 凸包+枚举 水题

    /* poj1873 The Fortified Forest 凸包+枚举 水题 用小树林的木头给小树林围一个围墙 每棵树都有价值 求消耗价值最低的做法,输出被砍伐的树的编号和剩余的木料 若砍伐价值相 ...

  9. Uva5211/POJ1873 The Fortified Forest 凸包

    LINK 题意:给出点集,每个点有个价值v和长度l,问把其中几个点取掉,用这几个点的长度能把剩下的点围住,要求剩下的点价值和最大,拿掉的点最少且剩余长度最长. 思路:1999WF中的水题.考虑到其点的 ...

随机推荐

  1. 《统计推断(Statistical Inference)》读书笔记——第4章 统计分布族

    数据分析工作中最常和多维随机变量打交道,第四章介绍了多维随机变量的基本知识,其中核心概念是条件分布和条件概率.条件分布和条件概率可以抽象出条件期望的概念,在随机分析的研究中,理解随机积分和鞅理论和关键 ...

  2. nginx tar.gz安装方法+简单静态文件配置

    1.首先安装依赖包(依赖包有点多,我们采用yum的方式来安装) yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel ...

  3. web项目引用Java项目,连接报错error HTTP Status 500 - Servlet execution threw an exception

    错误信息 项目背景: 一个web项目引用一个java Project,项目中添加了引用,但是打开页面访问,总报500错误.提示:servlet初始化错误. 环境:Eclipse luna JDK: 1 ...

  4. android学习笔记52——手势Gesture,增加手势、识别手势

    手势Gesture,增加手势 android除了提供了手势检测之外,还允许应用程序把用户手势(多个持续的触摸事件在屏幕上形成特定的形状)添加到指定文件中,以备以后使用 如果程序需要,当用户下次再次画出 ...

  5. 微分方程——基本概念和常微分方程的发展史

    1.2 基本概念和常微分方程的发展史 自变量.未知函数均为实值的微分方程称为实值微分方程:未知函数取复值或变量及未知函数均取复值时称为复值微分方程.若无特别声明,以下均指实变量的实值微分方程. 1.2 ...

  6. JavaScript 判断一个对象的数据类型。

    1.isString var isString1 = function (obj){ return Object.prototype.toString.call(obj)==="[objec ...

  7. PHP下的命令行执行 php -S localhost -t public

    PHP 的命令行模式     以下是 PHP 二进制文件(即 php.exe 程序)提供的命令行模式的选项参数,您随时可以通过 PHP -h 命令来查询这些参数. Usage: php [option ...

  8. [IIS]IIS扫盲(六)

    一:聊天室  聊天室的种类有很多,免费的聊天室也有很多,这些聊天室的ASP源码从网上都可以下载得到,我们就以毒爱聊天室为版本来教大家做.好,大家先下载毒爱聊天室,当然,本站软件下载里就有下载,下载的是 ...

  9. 67. Container With Most Water

    Container With Most Water Given n non-negative integers a1, a2, ..., an, where each represents a poi ...

  10. crosswalk-webview

    https://github.com/crosswalk-project/cordova-plugin-crosswalk-webview https://cordova.apache.org/doc ...