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

2023-12-27 02:38

本文主要是介绍2017北京ICPC -G - Liaoning Ship’s Voyage (HihoCoder - 1633)几何,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目网址https://cn.vjudge.net/problem/HihoCoder-1633

比赛的时候只是想到了,将三角形内部的点换成#,然后与三角形严格相交的走法的线段不可行,但是端点相交是可行的。

 

但是我们忽略了一种情况,就是端点与三角型相交,但是两个端点交于三角形的不同边,这种是错误的,后来我改了之后还想到了一种情况会wa,后来枚举情况,把我hy给搞懵了

 

看了看人家是怎么解决的(博客),发现人家思路很清晰:

case1:L的一个端点在外,一个在内。只要枚举L跟三角形所有边是否规范相交即可。

case2:L的两个端点都在三角形的边上,判断L的中点是否在三角形内部即可

case3:最难想到吧。。一个端点在边上,另一个端点经过了三角形的一个顶点,而且L的中点在三角形外部。。

只要将端点各自向内缩一小块即可。

 

但是后来发现自己的板子还用错了一个地方,就是判断点在线段上时,端点处应该也要判断一下的,但是我之前没有判断。

好了,终于ac了这个题了。

 

献上丑陋的代码:

#include <iostream>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <cstdio>
#include <queue>
#include <cmath>using namespace std;
const int maxn = 25;
struct Point
{double x,y;Point(double xx=0,double yy =0){x =xx;y = yy;}
//    void print()
//    {
//        cout<<x<<" "<<y<<endl;
//    }};typedef Point Vector;
Vector  operator+ (Vector A,Vector B)
{return Vector(A.x+B.x,A.y+B.y);
}
Vector operator -(Vector A,Vector B)
{return Vector(A.x-B.x,A.y-B.y);
}
Vector operator*(Vector A,double p)
{return Vector(A.x*p,A.y*p);
}
Vector operator/(Vector A,double p)
{return Vector(A.x/p,A.y/p);
}
bool operator <(const Point &a,const Point &b)
{return a.x<b.x||(a.x==b.x && a.y<b.y);
}
const double eps = 1e-8;
int dcmp(double x)
{if(fabs(x)<eps)return 0;elsereturn x<0?-1:1;
}
bool operator == (const Point& a,const Point &b)
{return dcmp(a.x-b.x)==0 && dcmp(a.y - b.y)==0;
}
double Dot(Vector A,Vector B)
{return A.x*B.x+A.y*B.y;
}
double Cross(Vector A,Vector B)
{return A.x*B.y - A.y*B.x;
}
bool SegmentProper(Point a1,Point a2,Point b1,Point b2)
{double c1= Cross(a2-a1,b1-a1),c2 = Cross(a2-a1,b2-a1);double c3 = Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
///就是wa下面这里了,还要注意连端点一块判断
bool OnSegment(Point p,Point a1,Point a2)
{
//   return dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dot(a1-p,a2-p))<0;if(dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dot(a1-p,a2-p))<0 ) return 1;return a1 == p || a2 == p;
}Point san[4];
int IsPointIN(Point p)
{int wn = 0;int n = 3;for(int i=0; i<n; i++){if(OnSegment(p,san[i],san[(i+1)%n]))return -1; //bianejieint k = dcmp(Cross(san[(i+1)%n]- san[i],p-san[i]));int d1 = dcmp(san[i].y-p.y);int d2 = dcmp(san[(i+1)%n].y-p.y);if(k>0 && d1<=0 && d2>0)wn++;if(k<0 && d2<=0 && d1>0)wn--;}if(wn!=0)return 1;//niebureturn 0;
}
int n;
char mp[maxn][maxn];
int dx[]= {0,0,1,-1,1,1,-1,-1};
int dy[]= {1,-1,0,0,-1,1,-1,1};
int vis[maxn][maxn];
struct node
{int x,y;int t;node(int xx=0,int yy=0,int tt=0){x =xx;y = yy;t =tt;}bool operator<(const node & s)const{return t>s.t;}
};
int oj1(int xx,int yy)
{if(xx>=0&&xx<n&&yy>=0&&yy<n&&!vis[xx][yy] && mp[xx][yy]=='.')return 1;return 0;
}
void change(Point &p1,Point &p2,double t)
{Vector v = p2-p1;p1 = p1 + v*t;v = v*(-1.0);p2 = p2 + v*t;
}
int oj2(int x,int y,int xx,int yy)
{Point p(x,y);Point p2(xx,yy);int ok1=0,ok2=0;for(int i=0; i<3; i++){if(SegmentProper(p,p2,san[i],san[(i+1)%3]))return 0;if(OnSegment(Point(x,y),san[i%3],san[(i+1)%3]))ok1 = 1;if(OnSegment(Point(xx,yy),san[i],san[(i+1)%3]))ok2 = 1;}if(ok1&&ok2){if(IsPointIN(Point((double)(xx+x)/2.0,(double)(yy+y)/2.0))==1)return 0;}change(p,p2,1e-3);if(IsPointIN(p)==1)return 0;if(IsPointIN(p2)==1)return 0;return 1;
}
int dfs(int a,int b)
{priority_queue<node> q;q.push(node(a,b,0));vis[0][0] = 1;while(q.size()){node a = q.top();q.pop();if(a.x==n-1&&a.y==n-1){return a.t;}for(int i=0; i<8; i++){int xx = a.x+dx[i];int yy = a.y+dy[i];if(!oj1(xx,yy))continue;if(!oj2(a.x,a.y,xx,yy))continue;vis[xx][yy] = 1;q.push(node(xx,yy,a.t+1));}}return -1;
}
char xx[maxn][maxn];
int main()
{while(~scanf("%d",&n)){memset(vis,0,sizeof(vis));for(int i=0; i<3; i++){scanf("%lf%lf",&san[i].x,&san[i].y);}//cout<<oj2(1,0,1,1)<<endl; //wa的数据for(int i=n-1; i>=0; i--)scanf("%s",xx[i]);for(int i=0; i<n; i++){for(int j=0; j<n; j++)mp[i][j] = xx[j][i];}for(int i=0; i<n; i++)for(int j=0; j<n; j++){if(IsPointIN(Point(i,j))==1){mp[i][j]='#';}}int ans =  dfs(0,0);printf("%d\n",ans);}return 0;
}
/*
3
0 0
1 0.5
2 01 0
1 1
*/

 

这篇关于2017北京ICPC -G - Liaoning Ship’s Voyage (HihoCoder - 1633)几何的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/541632

相关文章

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

poj 3304 几何

题目大意:给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出No!。 解题思路:如果存在这样的直线,过投影相交点(或投影相交区域中的点)作直线的垂线,该垂线(也是直线)必定与每条线段相交,问题转化为问是否存在一条直线和所有线段相交。 若存在一条直线与所有线段相交,此时该直线必定经过这些线段的某两个端点,所以枚举任意两个端点即可。

POJ 2318 几何 POJ 2398

给出0 , 1 , 2 ... n 个盒子, 和m个点, 统计每个盒子里面的点的个数。 const double eps = 1e-10 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;}struct Point{double x , y

poj 2653 几何

按顺序给一系列的线段,问最终哪些线段处在顶端(俯视图是完整的)。 const double eps = 1e-10 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;}struct Point{double x , y ;Point(){}Po

三维布尔运算对不规范几何数据的兼容处理

1.前言 上一篇文章谈过八叉树布尔运算,对于规范几何数据的情况是没有问题的。 在实际情况中,由于几何数据来源不一,处理和生成方式不一,我们无法保证进行布尔运算的几何数据都是规范的,对于不规范情况有时候也有需求,这就需要兼容不规范数据情况,当然这种兼容不是一味的让步,而是对于存在有限的不规范数据的兼容处理。 2.原始数据示例 下图是一个大坝模型和之上要对其进行布尔运算的立方体。 大坝模型由

CF#284 (Div. 2) C.(几何规律)

题目链接:http://codeforces.com/contest/499/problem/C 解题思路: 把两个点的坐标分别带入方程组,如果最后两个值相乘为负,即异号,计数器++。其中有一个有趣的现象,从A到B的最短步数,可以变化为求A和B之间夹了多少条直线,那么最后只要求出直线数,即可求出最小步数。 如果一条直线夹在A和B中间,那么把A和B的坐标带入后,所得值相乘一定为负。数据很

2014年ACM/ICPC亚洲区现场赛广州赛区总结

本来不想提这件事的,后来学姐找我谈心时提到这件事,我突然意识到在这件事情上我错了一次,明明答应的去参加这场比赛,最后临时决定不去......其实中间有很多很多原因 1:我和tyh,sxk临时不去主要是广州太远,我们身上money不够,呵呵。。。别笑我们,你以为我们是高富帅啊,去一趟广州消费要2个月的生活费,奖学金又没发,你让我找我妈要她辛辛苦苦挣来的工资吗?!从哈尔滨到广州单来回的火车票每个人就