题目
Tri_integral Summer Training 4
题意:
有n+1的结点的链,每条边(结点圆心距)100,每个结点半径为10,每次可以旋转45°,但是不能自交。求是否通过旋转某些结点使得最上面的结点完全包含在一个矩形内。
题解:
首先矩形每条边向内缩10,这样只要最上面的点的圆心在新矩形即可。然后枚举所有节点旋转的角度,加上判断是否自交和剪枝,不会超时的。
因为时间紧,代码写的很丑,请轻拍……
//Time:22ms //Memory:0KB //Length:2709B #include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <queue> #include <cmath> #include <set> #include <algorithm> #define EPS 1e-6 #define INF 1000000007 using namespace std; struct _node { double num; int ro; bool operator <(const _node &b) const { if(ro!=b.ro) return ro<b.ro; return num<b.num-EPS; } }; int dcmp(double x) { if(fabs(x)<EPS) return 0; return x<0? -1:1; } struct Point { double x,y; Point(){} Point(double a,double b):x(a),y(b){} Point operator-(const Point &a)const{return Point(x-a.x,y-a.y);} void input() { scanf("%lf%lf",&x,&y); } }; typedef Point Vector; double Cross(Vector a, Vector b) { return a.x*b.y-a.y*b.x; } bool Isinter(Point s1, Point e1,Point s2,Point e2) { if(min(s1.x,e1.x)<=max(s2.x,e2.x)&& min(s1.y,e1.y)<=max(s2.y,e2.y)&& min(s2.x,e2.x)<=max(s1.x,e1.x)&& min(s2.y,e2.y)<=max(s1.y,e1.y)&& dcmp(Cross(s2-s1,e2-s1))*dcmp(Cross(s2-e1,e2-e1))<=0&& dcmp(Cross(s1-s2,e1-s2))*dcmp(Cross(s1-e2,e1-e2))<=0) return 1; return 0; } bool Isin(Point a,Point b,Point c) { if(c.x>=a.x&&c.x<=b.x&&c.y>=a.y&&c.y<=b.y) return 1; return 0; } set<_node> se[10]; int n,ans; Point ldown,rup; double posx[11],posy[11]; const double sqrt2=sqrt(2.0)*50.0; double dir[8][2]={{0,100},{sqrt2,sqrt2},{100,0},{sqrt2,-sqrt2}, {0,-100},{-sqrt2,-sqrt2},{-100,0},{-sqrt2,sqrt2}}; int need[10]={0,1,2,3,4,3,2,1}; void dfs(int h,int sum,int ro,double x,double y) { if(sum>ans) return ; if(h==n) { if(Isin(ldown,rup,Point(x,y))) ans=min(ans,sum); return ; } _node node; node.num=x*10001+y; node.ro=sum; if(se[h].find(node)!=se[h].end()) return ; se[h].insert(node); posx[h]=x,posy[h]=y; if(h>=3) for(int i=h-3;i<h-2;++i) if(Isinter(Point(posx[h],posy[h]),Point(posx[h-1],posy[h-1]), Point(posx[i],posy[i]),Point(posx[i+1],posy[i+1]))) return ; for(int i=0;i<8;++i) if(i!=4) { int tro=(ro+i)%8; dfs(h+1,sum+need[i],tro,x+dir[tro][0],y+dir[tro][1]); } return ; } int main() { //freopen("/home/moor/Code/input","r",stdin); int ncase,x,y; scanf("%d",&ncase); while(ncase--) { scanf("%d",&n); scanf("%d%d",&x,&y); x+=10,y+=10; ldown=Point(x,y); scanf("%d%d",&x,&y); x-=10,y-=10; rup=Point(x,y); for(int i=0;i<n;++i) se[i].clear(); ans=INF; dfs(0,0,0,0.0,0.0); printf("%d\n",ans==INF?-1:ans); } return 0; }