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

题面

题意:给你一个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 }

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

时间: 2024-10-09 13:35:12

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

2017 ACM/ICPC 北京赛区小结 By JSB @ Reconquista

之前的蜜汁格式等待拷贝lsmll学长. Day -2 出发前晚上还训了一场.C题是个MST规律题,我傻乎乎地写了个状压,快写完才发现复杂度爆炸了:颜学长有一题似乎被卡常数了?然后就日常被二队虐了两个题.>_< Day -1 早上4:20起床,和John.lzw学长一起打车去机场. 在飞机上,风学长悉心指导我如何优雅地向空姐要四杯饮料>< 之前听说川航的空餐很不错,终于尝到了呢! 在翔景轩酒店安顿好后,大家就迫不及待地去必胜客.吃饱后我还强行往嘴里塞披萨--学生打八折,大家都吃得挺欢

《ACM/ICPC 算法训练教程》读书笔记 之 数据结构(线段树详解)

依然延续第一篇读书笔记,这一篇是基于<ACM/ICPC 算法训练教程>上关于线段树的讲解的总结和修改(这本书在线段树这里Error非常多),但是总体来说这本书关于具体算法的讲解和案例都是不错的. 线段树简介 这是一种二叉搜索树,类似于区间树,是一种描述线段的树形数据结构,也是ACMer必学的一种数据结构,主要用于查询对一段数据的处理和存储查询,对时间度的优化也是较为明显的,优化后的时间复杂为O(logN).此外,线段树还可以拓展为点树,ZWK线段树等等,与此类似的还有树状数组等等. 例如:要将

2017 ACM/ICPC(北京)总结

这个季节的,北京真的很冷. 下午的热身赛,我依然先去敲一道搜索题,但是很不幸这道搜索题坑点还是蛮多的,浪费了好长时间后依然没能A掉,期间Codeblocks崩溃一次使得代码完全丢失,在队友的建议下便暂时放弃去做计算几何题目,很庆幸计算几何的题目并不算很难(求二分+两圆相交面积)很快1A,A掉后便继续去做难道搜索题,因为我感觉自己的状态比较差,便让队友去敲,队友实现代码后因为对题意的理解有误,WA了几发之后才过掉,之后的题目是一道网络流,因为中间耽误了一段时间,继续敲网络流时间可能不够,所以我们队

hihoCoder 1578 Visiting Peking University 【贪心】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

#1578 : Visiting Peking University 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Ming is going to travel for n days and the date of these days can be represented by n integers: 0, 1, 2, -, n-1. He plans to spend m consecutive days(2 ≤ m ≤ n)in Beijing. Durin

hihoCoder 1584 Bounce 【数学规律】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

#1584 : Bounce 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 For Argo, it is very interesting watching a circle bouncing in a rectangle. As shown in the figure below, the rectangle is divided into N×M grids, and the circle fits exactly one grid. The bouncing

hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛-题目9 : Minimum【线段树】

https://hihocoder.com/problemset/problem/1586 线段树操作,原来题并不难..... 要求乘积最小只要求区间内最大值.最小值和绝对值小的数,再判断min,max正负就行了. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define lson l,

hihocoder 1584 Bounce (数学 &amp;&amp; 规律) ACM-ICPC北京赛区2017网络赛

题意: 给定一副n*m的格子图, 问从左上角的点开始往右下角滑,碰到墙壁就反弹, 碰到角落就停止, 问恰好经过一次的格子有多少个. 如图,恰好经过一次的格子有39个. 分析: 首先要引入两个概念, "路径长","格子数". 路径长指的是整段路程的长度,如果走过同一个格子两次那么就算是2步. 格子数指的是整段路程经过的格子. 如果一个图是9*9(形如n*n)的, 那么就是从左上角一直到右下角, 走过的"路径长"恰好等于"格子数"

2017 ACM/ICPC 新疆赛区 I 题 A Possible Tree 带权并查集

传送门 题意:给定一棵带权树的形态, 但是并不知道每天条边的具体权重. 然后给m个信息, 信息格式为u v val, 表示在树上u 到 v 的路径上经过的边的权重的异或和为val, 问前面最多有多少个信息是不冲突的. 思路:首先很明显的我们要维护一系列不知道的信息, 看冲不冲突的那就是带权并查集没跑了, 此时r[v] 表示v到这棵树的根节点(虽然题目没给, 但是我们可以假设一个)的路径异或和, 那么此时的每条信息相当于是告诉你r[u] ^ r[v]的值, 注意异或的特性. 所以对于每条信息维护好

2014 ACM/ICPC 牡丹江赛区现场赛

最近突然感觉状态不佳,可能是天冷的缘故? 赛后来做牡丹江赛区的题目 [A]3819 Average Score -- 签到题 [B] [C] [D] [E] [F] [G] [H] [I] [J] [K]3829 Known Notation -- 贪心 + 模拟 [A]3819 Average Score -- 签到题 Average Score Time Limit: 2 Seconds                                     Memory Limit: 65