poj1873The Fortified Forest

链接

居然是WF的水题~

二进制枚举砍哪些树,剩余的树围成一个凸包。

因为传数组WA了两发,忘记修改排序数组中的p[0];

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 20
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 struct point
 18 {
 19     int x,y;
 20     int vi,li;
 21     point(int x=0,int y=0):x(x),y(y){}
 22 }p[N],q[N],ch[N];
 23 int o[N],f[N];
 24 typedef point pointt;
 25 pointt operator -(point a,point b)
 26 {
 27     return point(a.x-b.x,a.y-b.y);
 28 }
 29 int dcmp(double x)
 30 {
 31     if(fabs(x)<eps) return 0;
 32     return x<0?-1:1;
 33 }
 34 double cross(point a,point b)
 35 {
 36     return 1.0*a.x*b.y-a.y*b.x;
 37 }
 38 double mul(point p0,point p1,point p2)
 39 {
 40     return cross(p1-p0,p2-p0);
 41 }
 42 double dis(point a)
 43 {
 44     return sqrt(1.0*a.x*a.x+a.y*a.y);
 45 }
 46 bool cmp(point a,point b)
 47 {
 48     if(dcmp(mul(q[0],a,b))==0)
 49         return dis(a-q[0])<dis(b-q[0]);
 50     else
 51         return dcmp(mul(q[0],a,b))>0;
 52 }
 53 double Graham(int n)
 54 {
 55     if(n<=1) return 0;
 56     if(n==2) return 2*dis(q[0]-q[1]);
 57     int i,k = 0,top;
 58     point tmp;
 59     for(i = 0 ; i < n; i++)
 60     {
 61         if(q[i].y<q[k].y||(q[i].y==q[k].y&&q[i].x<q[k].x))
 62             k = i;
 63     }
 64     if(k!=0)
 65     {
 66         tmp = q[0];
 67         q[0] = q[k];
 68         q[k] = tmp;
 69     }
 70     sort(q+1,q+n,cmp);
 71     ch[0] = q[0];
 72     ch[1] = q[1];
 73     top = 1;
 74     for(i = 2; i < n ; i++)
 75     {
 76         while(top>0&&dcmp(mul(ch[top-1],ch[top],q[i]))<0)
 77             top--;
 78         top++;
 79         ch[top] =q[i];
 80     }
 81     ch[top+1] = ch[0];
 82     double len = 0;
 83     for(i = 0 ; i <= top ; i++)
 84     len+=dis(ch[i]-ch[i+1]);
 85     return len;
 86 }
 87 int main()
 88 {
 89     int n,i,j,g;
 90     int kk = 0;
 91     while(scanf("%d",&n)&&n)
 92     {
 93         for(i = 0 ; i <n ;i++)
 94         scanf("%d%d%d%d",&p[i].x,&p[i].y,&p[i].vi,&p[i].li);
 95         int num;
 96         int ans = INF;
 97         double res = 0;
 98         for(i = 0 ; i < (1<<n) ; i++)
 99         {
100             g = 0;
101             int gg = 0;
102             int tv = 0;
103             double tlen = 0;
104             for(j = 0 ;j < n; j++)
105             {
106                 if((1<<j)&i)
107                 {
108                     f[gg++] = j;
109                     tlen+=p[j].li;
110                     tv += p[j].vi;
111                 }
112                 else q[g++] = p[j];
113             }
114             double len = Graham(g);
115             if(dcmp(tlen-len)>=0)
116             {
117                 if(ans>tv||(ans==tv&&num>gg))
118                 {
119                     ans = tv;
120                     num = gg;
121                     res = tlen-len;
122                     //cout<<len<<" "<<i<<endl;
123                     
124                     
125                     for(j = 0 ; j < gg ; j++)
126                     o[j] = f[j]+1;
127                 }
128             }
129         }
130         if(kk) puts("");
131         printf("Forest %d
",++kk);
132         printf("Cut these trees: ");
133         for(i = 0; i < num-1; i++)
134         printf("%d ",o[i]);
135         if(num)
136         printf("%d
",o[num-1]);
137         printf("Extra wood: %.2f
",res);
138     }
139     return 0;
140 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3886545.html