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 }