POJ 3135 Polygons on the Grid(枚举+凸包)

题目大意是让你用这n条边放在网格上构成凸包,并且边的两端点必须在网格上。

那么比较容易想到的就是枚举可能情况,因为这样的勾股数组成情况不多,因此可以直接枚举所有连出去的边反映在坐标轴上的所有情况,最后判断是否回到起点并且绕城一个凸包。

但是样例三每条边有最多36个方向,那么366*6!显然会超时,我们就需要一些剪枝。

1.第一条边固定住,那么我们的枚举边的顺序的复杂度变成了5!.

2.枚举到最后一个点的时候,不需要再将次边连出去判断是否回到起点,直接判断起点到该点的距离是否为这条边的长度即可,复杂度降成365.

3.每次往下搜索的时候都要去判断是否把这个点定住,当前的所有点仍然是一个凸包,因为满足的条件的凸包不多,所以这部分剪枝剪得比较多.

附赠数据:

6

60 203 113 164 169 131 

6

185 198 159 109 69 120

6

246 261 281 217 240 225

6

290 124 130 16 112 120

0

41636

37323

125526

32088

  1 //      ——By DD_BOND
  2 
  3 //#include<bits/stdc++.h>
  4 //#include<unordered_map>
  5 //#include<unordered_set>
  6 #include<functional>
  7 #include<algorithm>
  8 #include<iostream>
  9 //#include<ext/rope>
 10 #include<iomanip>
 11 #include<climits>
 12 #include<cstring>
 13 #include<cstdlib>
 14 #include<cstddef>
 15 #include<cstdio>
 16 #include<memory>
 17 #include<vector>
 18 #include<cctype>
 19 #include<string>
 20 #include<cmath>
 21 #include<queue>
 22 #include<deque>
 23 #include<ctime>
 24 #include<stack>
 25 #include<map>
 26 #include<set>
 27 
 28 #define fi first
 29 #define se second
 30 #define MP make_pair
 31 #define pb push_back
 32 #define INF 0x3f3f3f3f
 33 #define pi 3.1415926535898
 34 #define lowbit(a)  (a&(-a))
 35 #define lson l,(l+r)/2,rt<<1
 36 #define rson (l+r)/2+1,r,rt<<1|1
 37 #define Min(a,b,c)  min(a,min(b,c))
 38 #define Max(a,b,c)  max(a,max(b,c))
 39 #define debug(x)  cerr<<#x<<"="<<x<<"\n";
 40 
 41 //#pragma GCC optimize(3)
 42 //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
 43 
 44 using namespace std;
 45 
 46 typedef long long ll;
 47 typedef pair<int,int> P;
 48 typedef pair<ll,ll> Pll;
 49 typedef unsigned long long ull;
 50 
 51 const int seed=131;
 52 const ll LLMAX=2e18;
 53 const int MOD=1e9+7;
 54 const double eps=1e-8;
 55 const int MAXN=1e6+10;
 56 const int hmod1=0x48E2DCE7;
 57 const int hmod2=0x60000005;
 58 
 59 inline ll sqr(ll x){ return x*x; }
 60 inline int sqr(int x){ return x*x; }
 61 inline double sqr(double x){ return x*x; }
 62 ll __gcd(ll a,ll b){ return b==0? a: __gcd(b,a%b); }
 63 ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}
 64 inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
 65 
 66 struct Point{
 67     int x,y;
 68     Point(){ x=y=0; }
 69     Point(int _x,int _y):x(_x),y(_y){}
 70     inline Point operator -(const Point &n)const{
 71         return Point(x-n.x,y-n.y);
 72     }
 73     inline int operator *(const Point &n)const{
 74         return x*n.x+y*n.y;
 75     }
 76     inline int operator ^(const Point &n)const{
 77         return x*n.y-y*n.x;
 78     }
 79 };
 80 
 81 Point loc[10];
 82 int n,sum,ans,l[10];
 83 vector<Point>vec[310];
 84 
 85 inline void dfs(int p,int x,int y,int res,int area){
 86     if(p==n-1){
 87         if(sqr(l[p])!=x*x+y*y)    return ;
 88         ans=max(ans,area/2);
 89     }
 90     else{
 91         for(int i=0;i<(int)vec[l[p]].size();i++){
 92             if(p==0&&(vec[l[p]][i].x<0||vec[l[p]][i].y<0||vec[l[p]][i].x<vec[l[p]][i].y))  continue;
 93             Point tmp(x+vec[l[p]][i].x,y+vec[l[p]][i].y);
 94             if(p==0||(p>=1&&
 95                 ( ((loc[p]-loc[p-1])^(tmp-loc[p]))>0||( ((loc[p]-loc[p-1])^(tmp-loc[p]))==0&&((loc[p]-loc[p-1])*(tmp-loc[p]))>0 ) )&&
 96                 ( ((tmp-loc[p])^(Point(0,0)-tmp))>0||( ((tmp-loc[p])^(Point(0,0)-tmp))==0&&((tmp-loc[p])*(Point(0,0)-tmp))>0 ) )&&
 97                 ( ((Point(0,0)-tmp)^loc[1])>0||( ((Point(0,0)-tmp)^loc[1])==0&&((Point(0,0)-tmp)*loc[1])>0 ) )&&
 98                 tmp.x*tmp.x+tmp.y*tmp.y<=sqr(sum-res-l[p]) ) ){
 99                 int now=area;
100                 loc[p+1]=tmp;
101                 if(p>=1)    now+=loc[p]^loc[p+1];
102                 dfs(p+1,tmp.x,tmp.y,res+l[p],now);
103             }
104         }
105     }
106 }
107 
108 int main(void)
109 {
110     loc[0]=Point(0,0);
111     for(int i=-300;i<=300;i++)
112         for(int j=-300;j<=300;j++){
113             int p=i*i+j*j;
114             int sq=round(sqrt(p));
115             if(sq>300||sq*sq!=p)  continue;
116             vec[sq].pb(Point(i,j));
117         }
118     while(scanf("%d",&n)&&n){
119         sum=0;  ans=-1;
120         for(int i=0;i<n;i++)    scanf("%d",&l[i]),sum+=l[i];
121         sort(l,l+n);
122         do{ dfs(0,0,0,0,0); }while(next_permutation(l+1,l+n));
123         if(ans==0)  ans=-1;
124         printf("%d\n",ans);
125     }
126     return 0;
127 }
posted @ 2019-10-14 17:27  DD_BOND  阅读(197)  评论(0编辑  收藏  举报