题目大意:一个图上有n*n个点,然后从起点走到终点,然后需要绕过三角形和“#”,问一个最短路径
分析:由于边上的点和端点都是能走的,我在扩展边的时候,判断该边与三角形是否有焦点,我原先是判断线段与线段的交点,然后判断点是否在三角形内部,后来发现如果一个线段的起点和终点都不在三角形内部的话,也是有可能穿过三角形的,所以后来我们枚举了线段上的100个点,判断是否在三角形内部

#include <bits/stdc++.h>
using namespace std;
char mp[50][50];
int dist[50][50];
const int inf=0x3f3f3f3f;
double eps=1e-8;
int n;
struct point
{double x,y;point(double X=0,double Y=0){x=X,y=Y;}
};
point operator +(point a,point b)
{return point(a.x+b.x,a.y+b.y);
}
point operator -(point a,point b)
{return point(a.x-b.x,a.y-b.y);
}
point operator *(point a,double p)
{return point(a.x*p,a.y*p);
}
point operator /(point a,double p)
{return point(a.x/p,a.y/p);
}
double len(point a)
{return sqrt(a.x*a.x+a.y*a.y);
}
double dot(point a,point b)
{return a.x*b.x+a.y*b.y;
}
double cross(point a,point b)
{return a.x*b.y-a.y*b.x;
}
int dcmp(double x)
{if(fabs(x)<eps) return 0;else return x<0?-1:1;
}
bool operator == (point a,point b)
{if(dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0)return true;else return false;
}
bool segment(point a,point b,point c,point d)
{double c1 = cross(b-a,c-a);double c2 = cross(b-a,d-a);double d1 = cross(d-c,a-c);double d2 = cross(d-c,b-c);return dcmp(c1)*dcmp(c2)<0&&dcmp(d1)*dcmp(d2)<0;
}
double dists(point p,point a,point b)
{if(a==b) return len(p-a);point v1 = b-a,v2 = p-a,v3=p-b;if(dcmp(dot(v1,v2))<0) return len(v2);else if(dcmp(dot(v1,v3))>0) return len(v3);return fabs(cross(v1,v2))/len(v1);
}
point tri[5];
int pointin(point p,point *a,int n)
{int wn = 0,k,d1,d2;for(int i=1; i<=n; i++){if(dcmp(dists(p,a[i],a[i%n+1]))==0) return 0;k = dcmp(cross(a[i%n+1]-a[i],p-a[i]));d1 = dcmp(a[i].y-p.y);d2 = dcmp(a[i%n+1].y-p.y);if(k>0&&d1<=0&&d2>0) wn++;if(k<0&&d2<=0&&d1>0) wn--;}if(wn) return 1;else return 0;
}
bool check(int x,int y,int fx,int fy)
{if(fx<0||fx>=n||fy<0||fy>=n)return false;if(mp[x][y]=='#'||mp[fx][fy]=='#')return false;point a,b,c;a.x=y;a.y=x;b.x=fy;b.y=fx;for(int i=1; i<=3; i++){if(segment(a,b,tri[i],tri[i%3+1])) return false;}if(pointin(a,tri,3)) return false;if(pointin(b,tri,3)) return false;for(int i=1;i<=100;i++){double p = i*0.01;c.x=a.x+(b.x-a.x)*p;c.y = a.y+(b.y-a.y)*p;if(pointin(c,tri,3)) return false;}return true;
}
int fx[8] = {0, 0, 1,-1, 1, 1,-1,-1};
int fy[8] = {1,-1, 0, 0, 1,-1, 1,-1};
int d[500];
bool bfs(int s, int t)
{memset(d,-1,sizeof(d));queue<int> q;q.push(s*n+t);d[s*n+t]=0;while(!q.empty()){int u  = q.front();q.pop();int x = u/n;int y = u%n;if(u == n*n-1)  return true;for(int i = 0; i < 8; i++){int fx1 = x + fx[i];int fy1 = y + fy[i];if(check(x,y,fx1,fy1) && d[fx1*n+fy1] == -1){d[fx1*n+fy1] = d[u] + 1;q.push(fx1*n+fy1);}}}return false;
}int main()
{while(~scanf("%d",&n)){for(int i=1; i<=3; i++){scanf("%lf%lf",&tri[i].x,&tri[i].y);}/*point st=point(1.5,1);cout<<pointin(st,tri,3)<<endl;*/for(int i=n-1; i>=0; i--){scanf("%s",mp[i]);}if(bfs(0,0)){printf("%d\n",d[n*n-1]);}else printf("-1\n");}return 0;
}
/*
4
1 1 2 2 0 2
#...
#.##
#.##
..##*/

2017北京区域赛 G - Liaoning Ship’s Voyage【计算几何+bfs】相关推荐

  1. 2017ICPC北京现场赛G Liaoning Ship’s Voyage(BFS+点在多边形内判定)

    题目链接:https://cn.vjudge.net/problem/HihoCoder-1633 题意:有一个nxn的海域,海域上有两类点,一种是点,一种是#,#不可以走,还有给你三个顶点坐标(可能 ...

  2. 2017北京ICPC -G - Liaoning Ship’s Voyage (HihoCoder - 1633)几何

    题目网址https://cn.vjudge.net/problem/HihoCoder-1633 比赛的时候只是想到了,将三角形内部的点换成#,然后与三角形严格相交的走法的线段不可行,但是端点相交是可 ...

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

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

  4. (2015)北京区域赛总结+回忆录

    从去年7月跟着学长们入坑,到今年11月去北京比赛,一年多的时间就这样转眼度过,现在坐在电脑面前码字时大脑却一片空白,不知道从何说起.想起去年暑假的时候,每天都是8点多到实验室晚上10点回宿舍,顿顿和学 ...

  5. acm2015北京区域赛游记

    一只完全由大二组成的队伍第一次参加区域赛,最后压铜尾,这可能是上大学后做过最刺激的事情了.. 不像许多其他的大神,,接触算法时间太晚了,都是大一才开始学C语言,跟大部分oi大爷比起来差太远了→_→ → ...

  6. 星辰天合获得鲲鹏应用创新大赛 2022 北京区域赛决赛一等奖

    2022 年 8 月 30 日,以 "数智未来,因你而来" 为主题的统信创客北京・鲲鹏应用创新大赛 2022 北京区域决赛于北京鲲鹏联合创新中心成功举办,XSKY星辰天合团队的参选 ...

  7. 2017 ACM-ICPC 北京区域赛记录

    ------------------------------------------------------------------------------ 出发日 拖着一个大箱子走是真的累. 下午三 ...

  8. 2017乌鲁木齐区域赛D题Fence Building

    题目链接:点击打开链接 现场赛的时候想了一个整场都没推出来,xjb推出个式子来也不会写最后打铁...一直都知道这是一道公式题,就是不知道是啥公式,赛后才知道得用欧拉公式...平面内的区域个数=平面内的 ...

  9. 2018北京区域赛总结

    因为这次北京之行要花费四五天,临行前,我将所有课程的作业都做完了,甚至连回来要上的课的都提前准备了.万万没想到,jsp老师突然说要期中考,这令我心中有些烦躁,有点担心学业会被这次比赛搞砸.犹豫了一下, ...

  10. 2016北京区域赛E UVAlive 7672 题目:What a Ridiculous Election 带约束条件的BFS

    这几天做的北京的模拟,当时被这个题给卡住了,自己写的BFS,一直WA,结束后对拍才找到自己的致命错误 自己做的时候直接通过最优情况去推导最有情况,导致自己掉进死胡同了 这里举一个例子,比如变成0103 ...

最新文章

  1. Ubuntu 上创建常用磁盘阵列
  2. python 守护线程 join_Python多线程threading join和守护线程setDeamon原理详解
  3. R语言ggplot2可视化、使用axis.ticks.length函数设置坐标轴间隔标签竖线的长度、并设置坐标轴间隔标签在图像内部(刻度标记放置在图像内部)
  4. lovely desktop
  5. require用法php,php中的require到底是函数还是语法
  6. 【转】Python 简介
  7. Android开源介绍-UI组件
  8. Swap空间利用率不释放
  9. SAP Fiori internationalization(国际化)实现的一些例子
  10. mamcache登录、_gomemcache首页、文档和下载 - memcache客户端库 - Go语言中文网 - Golang中文社区...
  11. 数据库工作笔记009---Centos中导出mysql数据库
  12. 天猫轮播代码一秒美工万能淘宝轮播全屏轮播代码教程分享店铺装修全屏代码海报热点1920 居中显示圆点轮播海报
  13. 药品数据查询系统工具(非付费官网50个)
  14. padavan手动安装php
  15. 关于智能机器人的一些伦理道德问题
  16. 图像文件的读写和转换——BMP转YUV
  17. 我的世界服务器武器修改伤害,我的世界改伤害指令 | 手游网游页游攻略大全
  18. 封装一个常用的js工具类
  19. Workbook对象的方法总结(二)
  20. 前端|利用canvas画布制作地球轨道

热门文章

  1. android 处理闪屏
  2. opencv convertTo函数
  3. 0x000000c5(0X000000C5蓝屏是什么意思)
  4. python 0基础学习笔记6:OS模块、窗口控制、语言、内存修改
  5. Python2—0704笔记
  6. 探讨:Mac真的有必要安装双系统吗
  7. JSP之java.lang.ClassNotFoundException
  8. HTTPS 自签名证书 实现边下边播 方案
  9. (未解决)SpringMVC学习——为什么网址不是locahost而是desktop-nottqjs(如图)
  10. <C++>详解类对象作为类成员时调用构造和析构的时机及静态成员解释