码迷,mamicode.com
首页 > 其他好文 > 详细

hihoCoder-1633 ACM-ICPC北京赛区2017 G.Liaoning Ship’s Voyage 线段与三角形规范相交

时间:2018-10-21 21:58:13      阅读:300      评论:0      收藏:0      [点我收藏+]

标签:com   href   scanf   cross   build   can   判断   push   eps   

题面

题意:给你一个20*20的地图,起点(0,0),终点(n-1,n-1),有障碍的点为‘#’,每次可以向8个方向走一步,还给了一个三角形,除了障碍以外,到这8个方向上的点的线段如果没有与三角形相交,那么就可以到达,问最少步数

题解:主要是判断线段与三角形的相交,去年在现场和大多题解都是慢慢讨论,因为这个线段其实可以在边上,可以与三角形有交点,

         今天重现才想到,只需要线段上有一点在三角形内部就不能走,坐标范围不大,直接枚举线段上200个点,挨着判断就行

         在判断点在三角形内部时,注意顺时针逆时针啊,板子注意啊

       

  1 #include<bits/stdc++.h>
  2 const int inf=0x7fffffff/3;
  3 const double eps=1e-7;
  4 using namespace std;
  5 int dcmp(double x)
  6 {
  7     return (x>eps)-(x<-eps);
  8 }
  9 struct point
 10 {
 11     double x,y;
 12     point(){}
 13     point(double x,double y):x(x),y(y){ }
 14     point operator - (const point b){return point(x-b.x,y-b.y);}
 15 }a[4];
 16 double dot(point a,point b){return a.x*b.x+a.y*b.y;}
 17 double cross(point a,point b){return a.x*b.y-a.y*b.x;}
 18 
 19 int n,m,t,h,en,dis[410],used[500];
 20 int id[22][22],p,head[500];
 21 char x[22];
 22 int dx[8]={0,1,1,1,0,-1,-1,-1};
 23 int dy[8]={1,1,0,-1,-1,-1,0,1};
 24 queue<int>q;
 25 struct rec
 26 {
 27     int go,next;
 28 }eg[6000];
 29 void build(int a,int b)
 30 {
 31     p++;
 32     eg[p].go=b;
 33     eg[p].next=head[a];
 34     head[a]=p;
 35 }
 36 bool pointin(point p)
 37 {
 38     return dcmp(cross(a[1]-a[0],p-a[0]))>0 && dcmp(cross(a[2]-a[1],p-a[1]))>0 && dcmp(cross(a[0]-a[2],p-a[2]))>0;
 39 }
 40 
 41 bool check(point x,point y)
 42 {
 43     double ax=y.x-x.x;
 44     double ay=y.y-x.y;
 45     for (double i=1;i<=200;i=i+1.0)
 46     {
 47         point t;
 48         t.x=x.x+ax/200.0*i;
 49         t.y=x.y+ay/200.0*i;
 50         if (pointin(t)==1) return 0;
 51     }
 52     return true;
 53 }
 54 
 55 void spfa(int n)
 56 {
 57     memset(used,0,sizeof(used));
 58     while (!q.empty())q.pop();
 59     for (int i=2;i<=n;i++) dis[i]=inf;
 60     q.push(1);
 61     used[1]=1;
 62     dis[1]=0;
 63     while (!q.empty())
 64     {
 65         int x=q.front();q.pop();
 66         for (int u=head[x];u;u=eg[u].next)
 67         {
 68             int v=eg[u].go;
 69             if (dis[x]+1<dis[v])
 70             {
 71                 dis[v]=dis[x]+1;
 72                 if (!used[v])
 73                 {
 74                     q.push(v);
 75                     used[v]=1;
 76                 }
 77             }
 78         }
 79         used[x]=0;
 80     }
 81 }
 82 
 83 int main()
 84 {
 85     while (scanf("%d",&n)!=EOF)
 86     {
 87         p=0;
 88         memset(head,0,sizeof(head));
 89         memset(id,0,sizeof(id));
 90         for (int i=0;i<3;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
 91         if (dcmp(cross(a[1]-a[0],a[2]-a[0]))<0) swap(a[1],a[2]);
 92 
 93         for (int i=n-1;i>=0;i--)
 94         {
 95             scanf("%s",x);
 96             for (int j=0;j<n;j++)
 97                 if (x[j]==# || pointin(point(j,i))==1) id[i][j]=-1;
 98         }
 99         if (id[0][0]==-1 || id[n-1][n-1]==-1)
100         {
101             puts("-1");
102             continue;
103         }
104         t=0;
105         for (int i=0;i<n;i++)
106         for (int j=0;j<n;j++)
107             if (id[i][j]!=-1)
108                 {
109                     t++;
110                     id[i][j]=t;
111                 }
112 
113         for (int i=0;i<n;i++)
114             for (int j=0;j<n;j++)
115             {
116                 if (id[i][j]==-1) continue;
117                 for (int k=0;k<8;k++)
118                 {
119                     int nx=i+dx[k];
120                     int ny=j+dy[k];
121                     if (id[nx][ny]==-1 || nx<0 || nx>=n || ny<0 || ny>=n) continue;
122                     if (check(point(j,i),point(ny,nx)))
123                     {
124                             //printf("%d %d\n",id[i][j],id[x][y]);
125                         build(id[i][j],id[nx][ny]);
126                     }
127                 }
128             }
129 
130         en=id[n-1][n-1];
131         spfa(en);
132         if (dis[en]==inf)puts("-1");else printf("%d\n",dis[en]);
133     }
134     return 0;
135 }

 

hihoCoder-1633 ACM-ICPC北京赛区2017 G.Liaoning Ship’s Voyage 线段与三角形规范相交

标签:com   href   scanf   cross   build   can   判断   push   eps   

原文地址:https://www.cnblogs.com/qywhy/p/9826722.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!