简单凸包+暴力枚举。
/*
几何凸包+暴力
*/
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
typedef long long int64;
//typedef __int64 int64;
typedef pair<int64,int64> PII;
#define MP(a,b) make_pair((a),(b))
const int inf = 0x3f3f3f3f;
const double pi=acos(-1.0);
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
const double eps = 1e-8;
const int maxm = 1005;
const int maxn = 16;
struct Point2 {
int x,y;
double val,len;
bool ok;//ok = true 需要去掉的点
}pnt[ maxn ];
int cur[ maxn ];
int cnt_cur;
double val_cur,ans1;
int best[ maxn ];
int cnt_best;
double val_best,ans2;
double Len1,Len2;
struct Point {
double x,y;
bool operator < ( const Point &t ) const {
return y<t.y||( y==t.y&&x<t.x );
}
}a[ maxn ],res[ maxn ];
double xmult( Point sp,Point ep,Point op ){
return (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x);
}
double dist( int i,int j ){
return sqrt( (res[i].x-res[j].x)*(res[i].x-res[j].x)+(res[i].y-res[j].y)*(res[i].y-res[j].y) );
}
int Graham( int n ){
int top = 1;
sort( a,a+n );
if( n==0 ) return 0;
else res[0] = a[0];
if( n==1 ) return 1;
else res[1] = a[1];
if( n==2 ) return 2;
else res[2] = a[2];
for( int i=2;i<n;i++ ){
while( top>0 && xmult(res[top],res[top-1],a[i])>=0 )
top--;
res[ ++top ] = a[i];
}
int len = top;
res[ ++top ] = a[ n-2 ];
for( int i=n-3;i>=0;i-- ){
while( top!=len && xmult( res[top],res[top-1],a[i])>=0 )
top--;
res[ ++top ] = a[i];
}
return top;
}
bool Solve( int n ){
double temp1 = 0;
int cc = 0;
for( int i=0;i<n;i++ ){
if( pnt[i].ok==false ){
a[ cc ].x = 1.0*pnt[ i ].x;
a[ cc ].y = 1.0*pnt[ i ].y;
cc++;
}
else temp1 += pnt[ i ].len;
}
int q = cc;
cc = Graham( q );
double temp2 = 0;
res[ cc ] = res[ 0 ];
for( int i=0;i<cc;i++ ){
temp2 += dist( i,i+1 );
}
ans1 = temp2;
Len1 = temp1;
if( temp2<=temp1 ) return true;
else return false;
}
int main(){
int n;
int Case = 1;
while( scanf("%d",&n),n ){
if( Case!=1 ) printf("\n");
for( int i=0;i<n;i++ ){
scanf("%d%d%lf%lf",&pnt[i].x,&pnt[i].y,&pnt[i].val,&pnt[i].len);
}
int N = (1<<n);
ans1 = ans2 = 0;
val_best = 9999999999.0;
for( int i=0;i<N;i++ ){
cnt_cur = 0;
val_cur = 0;
for( int j=0;j<n;j++ ){
if( i&(1<<j) ){
cur[ cnt_cur++ ] = j;
pnt[ j ].ok = true;
val_cur += pnt[ j ].val;
}
else
pnt[ j ].ok = false;
}
if( cnt_cur==n ) continue;
if( Solve(n)==true ){
//printf("Solve\n");
if( val_cur<val_best ){
val_best = val_cur;
for( int k=0;k<cnt_cur;k++ ){
best[ k ] = cur[ k ];
}
cnt_best = cnt_cur;
ans2 = ans1;
Len2 = Len1;
}
else if( val_cur==val_best ){
if( cnt_cur<cnt_best ){
for( int k=0;k<cnt_cur;k++ ){
best[ k ] = cur[ k ];
}
cnt_best = cnt_cur;
ans2 = ans1;
Len2 = Len1;
}
}
}
}
printf("Forest %d\n",Case++);
printf("Cut these trees: ");
for( int i=0;i<cnt_best;i++ )
printf("%d ",best[i]+1);
printf("\n");
printf("Extra wood: %.2lf\n",Len2-ans2);
}
return 0;
}
分享到:
相关推荐
poj 800+ 题目源代码,多年做题积累 包含各种类型经典题目
北大POJ1113-Wall【凸包】 解题报告+AC代码
北大POJ2031-Building a Space Station【Prim+计算几何】 POJ2031-Building a Space Station【Prim+计算几何】
O(nlogn)凸包问题 poj2187
北大POJ初级-计算几何学 解题报告+AC代码
2505 2521 2538 2546 2551 2590 2593 2601 2665 2680 2739 2752 2761 2762 2777 2800 2891 2893 2992 3030 3041 3132 3159 3187 3204 3270 3277 3281 3297 3321 3414 3436 3461 3650 3663 3664 3672 3740
北大POJ初级-简单搜索 解题报告+AC代码
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
NULL 博文链接:https://128kj.iteye.com/blog/1748635
POJ上做的一个凸包的题,可作为凸包的模板。
北大POJ1159-Palindrome 解题报告+AC代码
西北工业大学POJ试题C++答案代码+课程设计
NULL 博文链接:https://128kj.iteye.com/blog/1749213
北大POJ2002-Squares 解题报告+AC代码
poj1113 melkman算法求凸包, 使用STL
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码
北大POJ3009-Curling 2.0【DFS+Vector+回溯+剪枝】 解题报告+AC代码
凸包melkman算法cpp实现,通过poj1113题测试
北大POJ1207-The 3n + 1 problem 解题报告+AC代码