POJ 1873 The Fortified Forest 凸包 二进制枚举
n最大15,二进制枚举不会超时。枚举不被砍掉的树,然后求凸包
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include <cstring>
#define eps 1e-8
#define INF 1e9
using namespace std; const int MAXN = 20; struct Point
{
int x,y;
int v,l;
}; Point pot[MAXN];
int stck[MAXN],top; int sgn(double x)
{
if(fabs(x) < eps) return 0;
return x < 0 ? -1:1;
} int cross(Point p0,Point p1,Point p2) //计算叉积 p0p1 X p0p2
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
} double dis(Point p1,Point p2) //计算 p1p2的 距离
{
return sqrt((double)(p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
} bool cmp(Point p1,Point p2) //极角排序函数,角度相同则距离小的在前面
{
int tmp=cross(pot[0],p1,p2);
if(tmp>0) return true;
else if(tmp==0&&dis(pot[0],p1)<dis(pot[0],p2)) return true;
else return false;
} void init(int n) //输入,并把最左下方的点放在 pot[0]。并且进行极角排序
{
int i,k;
Point p0;
p0 = pot[0];
k=0;
for(i=1; i<n; i++)
{
if( (p0.y>pot[i].y) || ((p0.y==pot[i].y)&&(p0.x>pot[i].x)) )
{
p0 = pot[i];
k=i;
}
}
pot[k]=pot[0];
pot[0]=p0;
sort(pot+1,pot+n,cmp);
} void graham(int n)
{
int i;
if(n==1)
{
top=0;
stck[0]=0;
}
if(n==2)
{
top=1;
stck[0]=0;
stck[1]=1;
}
if(n>2)
{
for(i=0; i<=1; i++) stck[i]=i;
top=1; for(i=2; i<n; i++)
{
while(top>0&&cross(pot[stck[top-1]],pot[stck[top]],pot[i])<=0) top--;
top++;
stck[top]=i;
}
}
} Point p[MAXN]; int main()
{
// freopen("in.txt","r",stdin);
int n, val, len, minv, maxn, ans;
double exc;
int Case = 0;
while(~scanf("%d", &n) && n)
{
val = len = 0;
for(int i=0; i<n; i++)
{
scanf("%d%d%d%d", &p[i].x, &p[i].y, &p[i].v, &p[i].l);
val += p[i].v;
len += p[i].l;
}
minv = INF;
maxn = 0;
for(int i=1; i< (1<<n)-1; i++)
{
int cnt, tmp ,v ,l;
cnt = 0;
tmp = i;
v = val;
l = len;
for(int j=0; j<n; j++)
{
if(tmp&1)
{
pot[cnt++] = p[j];
v -= p[j].v;
l -= p[j].l;
}
tmp >>= 1;
}
init(cnt);
graham(cnt);
double d = 0;
for(int j=0; j<=top; j++)
d += dis(pot[stck[j]], pot[stck[(j+1)%(top+1)]]);
if(sgn(l - d) >= 0)
{
if(v < minv || (v == minv && cnt > maxn))
{
minv = v;
maxn = cnt;
ans = i;
exc = l - d;
}
}
}
printf("Forest %d\nCut these trees: ", ++Case);
for(int i=0; i<n; i++)
{
if((ans&1) == 0) printf("%d ", i+1);
ans >>= 1;
}
printf("\nExtra wood: %.2lf\n\n", exc);
}
return 0;
}
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 1 << 15 = 32768 直接枚举完全可行 卡在异常情况判断上很久,只有 顶点数 &g ...
- 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
题目传送门 题意:砍掉一些树,用它们做成篱笆把剩余的树围起来,问最小价值 分析:数据量不大,考虑状态压缩暴力枚举,求凸包以及计算凸包长度.虽说是水题,毕竟是final,自己状压的最大情况写错了,而且忘 ...
- POJ 1873 The Fortified Forest(凸包)题解
题意:二维平面有一堆点,每个点有价值v和删掉这个点能得到的长度l,问你删掉最少的价值能把剩余点围起来,价值一样求删掉的点最少 思路:n<=15,那么直接遍历2^15,判断每种情况.这里要优化一下 ...
- ●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 凸包+枚举 水题 用小树林的木头给小树林围一个围墙 每棵树都有价值 求消耗价值最低的做法,输出被砍伐的树的编号和剩余的木料 若砍伐价值相 ...
- POJ 1873 UVA 811 The Fortified Forest (凸包 + 状态压缩枚举)
题目链接:UVA 811 Description Once upon a time, in a faraway land, there lived a king. This king owned a ...
随机推荐
- linux下dmidecode命令获取硬件信息
linux下dmidecode命令获取硬件信息 2 A+ 所属分类:Linux 运维工具 dmidecode在 Linux 系统下获取有关硬件方面的信息.dmidecode 遵循 SMBIOS/DMI ...
- IT菜鸟之虚拟机VMware的安装
老师说过,如果想学好Linux,最好不要在实体机上安装Linux,因为学习需要经常折腾,在实体机上做实验,出现故障就要重新安装,这样绝大多数时间都会浪费在安装上. 这时我们需要一个工具,它就是虚拟机. ...
- MySQL 查询操作
目录 基本语法 查询常量 查看表达式 查询函数 查询指定字段 查询所有列 列别名 表别名 条件查询 条件查询运算符 逻辑查询运算符 排序与分页 排序查询(order by) 排序方式 limit 分组 ...
- object_pool对象池
object_pool对象池 object_pool是用于类实例(对象)的内存池,它能够在析构时调用所有已经分配的内存块调用析构函数,从而正确释放资源,需要包含以下头文件: #include < ...
- oracle实现通过logminer实现日志抓取分析
场景:现场库到前置库. 思考:使用触发器? 1.侵入性解决方案 2.需要时各种配置,不需要时又是各种配置 Change Data Capture:捕捉变化的数据,通过日志监测并捕获数据库的变动(包括数 ...
- Vue&Element 前端应用开发之菜单和路由的关系
我们一般的应用系统,菜单是很多功能界面的入口,菜单为了更好体现功能点的设置,一般都是动态从数据库生成的,而且还需要根据用户角色的不同,过滤掉部分没有权限的菜单:在Vue&Element的纯前端 ...
- MySQL 基础、安装、配置
1. MySQL 基础 1.1 什么是数据库? 1.2 数据库的类型 1.3 关系型数据库的优点 1.4 MySQL 简介 1.5 MySQL 数据类型 1.6 Mysql 存储引擎 1.7 MySQ ...
- 3D惯导Lidar SLAM
3D惯导Lidar SLAM LIPS: LiDAR-Inertial 3D Plane SLAM 摘要 本文提出了最*点*面表示的形式化方法,并分析了其在三维室内同步定位与映射中的应用.提出了一个利 ...
- 【Azure 应用服务】Azure Web App的服务(基于Windows 操作系统部署)在被安全漏洞扫描时发现了TCP timestamps漏洞
问题背景 什么是TCP timestamps(TCP 时间戳)? The remote host implements TCP Timestamps, as defined by RFC1323 (h ...
- 手把手教你彻底理解MySQL的explain关键字
数据库是程序员必备的一项基本技能,基本每次面试必问.对于刚出校门的程序员,你只要学会如何使用就行了,但越往后工作越发现,仅仅会写sql语句是万万不行的.写出的sql,如果性能不好,达不到要求,可能会阻 ...