xcoj1062
题意:给出一个闭合折线上的一堆点(不按顺序),然后再给一个点P,要求判断P是否在闭合折线内
sol attempt1:一开始觉得是个模板题的,后来发现不对劲:
给出的点并不按照顺序。这样模板大法就不行了(geiline函数是按顺序建line的,会错乱掉)
sol attempt2:手艹大法:先建立好图形,然后再判断:
从点P向外引射线,若射线与图形的边相交奇数次,说明P在图形内。
PS:本题测试数据好像有点不对劲:
对于这组数据:
很容易画出图:
很容易发现绿色点P应该是INSIDE的,但是testdata是OUTSIDE
围观了下标程。。。好像是对于多组数据标程忘了初始化数组了。当时现场也并没有人过orz
附我的code:
#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<iostream>
#include<sstream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<climits>
#include<complex>
#define mp make_pair
#define pb push_back
using namespace std;
const double eps=1e-;
const double pi=acos(-1.0);
const double inf=1e20;
const int maxp=; //多边形内点的数量,注意按需求调整 int sgn(double x)
{
if (fabs(x)<eps) return ;
if (x<) return -;
else return ;
} int dblcmp(double d)
{
if (fabs(d)<eps)return ;
return d>eps?:-;
} inline double sqr(double x){return x*x;}
struct point
{
double x,y;
point(){}
point(double _x,double _y):
x(_x),y(_y){};
void input()
{
scanf("%lf%lf",&x,&y);
}
void output()
{
printf("%.2f %.2f\n",x,y);
}
bool operator==(point a)const
{
return dblcmp(a.x-x)==&&dblcmp(a.y-y)==;
}
bool operator<(point a)const
{
return dblcmp(a.x-x)==?dblcmp(y-a.y)<:x<a.x;
} point operator +(const point &b)const
{
return point(x+b.x,y+b.y);
}
point operator -(const point &b)const
{
return point(x-b.x,y-b.y);
}
point operator *(const double &k)const
{
return point(x*k,y*k);
}
point operator /(const double &k)const
{
return point(x/k,y/k);
}
double operator ^(const point &b)const
{
return x*b.y-y*b.x;
}
double operator *(const point &b)const
{
return x*b.x+y*b.y;
} double len()
{
return hypot(x,y);
}
double len2()
{
return x*x+y*y;
}
double distance(point p)
{
return hypot(x-p.x,y-p.y);
}
point add(point p)
{
return point(x+p.x,y+p.y);
}
point sub(point p)
{
return point(x-p.x,y-p.y);
}
point mul(double b)
{
return point(x*b,y*b);
}
point div(double b)
{
return point(x/b,y/b);
}
double dot(point p)
{
return x*p.x+y*p.y;
}
double det(point p)
{
return x*p.y-y*p.x;
}
double rad(point a,point b)
{
point p=*this;
return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
}
point trunc(double r)
{
double l=len();
if (!dblcmp(l))return *this;
r/=l;
return point(x*r,y*r);
}
point rotleft()
{
return point(-y,x);
}
point rotright()
{
return point(y,-x);
}
point rotate(point p,double angle)//绕点p逆时针旋转angle角度
{
point v=this->sub(p);
double c=cos(angle),s=sin(angle);
return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
}
}; struct line
{
point a,b;
line(){}
line(point _a,point _b)
{
a=_a;
b=_b;
}
bool operator==(line v)
{
return (a==v.a)&&(b==v.b);
}
//倾斜角angle
line(point p,double angle)
{
a=p;
if (dblcmp(angle-pi/)==)
{
b=a.add(point(,));
}
else
{
b=a.add(point(,tan(angle)));
}
}
//ax+by+c=0
line(double _a,double _b,double _c)
{
if (dblcmp(_a)==)
{
a=point(,-_c/_b);
b=point(,-_c/_b);
}
else if (dblcmp(_b)==)
{
a=point(-_c/_a,);
b=point(-_c/_a,);
}
else
{
a=point(,-_c/_b);
b=point(,(-_c-_a)/_b);
}
}
void input()
{
a.input();
b.input();
}
void adjust()
{
if (b<a)swap(a,b);
}
double length()
{
return a.distance(b);
}
double angle()//直线倾斜角 0<=angle<180
{
double k=atan2(b.y-a.y,b.x-a.x);
if (dblcmp(k)<)k+=pi;
if (dblcmp(k-pi)==)k-=pi;
return k;
}
//点和线段关系
//1 在逆时针
//2 在顺时针
//3 平行
int relation(point p)
{
int c=dblcmp(p.sub(a).det(b.sub(a)));
if (c<)return ;
if (c>)return ;
return ;
}
bool pointonseg(point p)
{
return dblcmp(p.sub(a).det(b.sub(a)))==&&dblcmp(p.sub(a).dot(p.sub(b)))<=;
}
bool parallel(line v)
{
return dblcmp(b.sub(a).det(v.b.sub(v.a)))==;
}
//2 规范相交
//1 非规范相交
//0 不相交
int segcrossseg(line v)
{
int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
if ((d1^d2)==-&&(d3^d4)==-)return ;
return (d1==&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=||
d2==&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=||
d3==&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=||
d4==&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=);
}
int linecrossseg(line v)//*this seg v line
{
int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
if ((d1^d2)==-)return ;
return (d1==||d2==);
}
//0 平行
//1 重合
//2 相交
int linecrossline(line v)
{
if ((*this).parallel(v))
{
return v.relation(a)==;
}
return ;
}
point crosspoint(line v)
{
double a1=v.b.sub(v.a).det(a.sub(v.a));
double a2=v.b.sub(v.a).det(b.sub(v.a));
return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
}
double dispointtoline(point p)
{
return fabs(p.sub(a).det(b.sub(a)))/length();
}
double dispointtoseg(point p)
{
if (dblcmp(p.sub(b).dot(a.sub(b)))<||dblcmp(p.sub(a).dot(b.sub(a)))<)
{
return min(p.distance(a),p.distance(b));
}
return dispointtoline(p);
}
point lineprog(point p)
{
return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
}
point symmetrypoint(point p)
{
point q=lineprog(p);
return point(*q.x-p.x,*q.y-p.y);
}
}; struct Vector:public point
{
Vector(){}
Vector(double a,double b)
{
x=a; y=b;
}
Vector(point _a,point _b) //a->b
{
double dx=_b.x-_a.x;
double dy=_b.y-_a.y;
x=dx; y=dy;
}
Vector(line v)
{
double dx=v.b.x-v.a.x;
double dy=v.b.y-v.a.y;
x=dx; y=dy;
}
double length()
{
return (sqrt(x*x+y*y));
}
Vector Normal()
{
double L=sqrt(x*x+y*y);
Vector Vans=Vector(-y/L,x/L);
return Vans;
}
}; struct polygon
{
int n; //the number of points
int nl; //the number of lines
point p[maxp]; //0..n-1
line l[maxp]; //0..nl-1
/*
void input(int X)
{
n=X;
nl=X;
for (int i=0;i<n;i++)
{
p[i].input();
}
}
*/
void add(point q)
{
p[n++]=q;
}
/*
void getline()
{
for (int i=0;i<n;i++)
{
l[i]=line(p[i],p[(i+1)%n]);
}
}
*/ //3 点上
//2 边上
//1 内部
//0 外部
int relationpoint(point q)
{
int i,j;
for (i=;i<n;i++)
{
if (p[i]==q)return ;
}
//getline();
for (i=;i<nl;i++)
{
if (l[i].pointonseg(q))return ;
}
int cnt=;
for (i=;i<n;i++)
{
j=(i+)%n;
int k=dblcmp(q.sub(p[j]).det(p[i].sub(p[j])));
int u=dblcmp(p[i].y-q.y);
int v=dblcmp(p[j].y-q.y);
if (k>&&u<&&v>=)cnt++;
if (k<&&v<&&u>=)cnt--;
}
return cnt!=;
}
/*
//1 在多边形内长度为正
//2 相交或与边平行
//0 无任何交点
int relationline(line u)
{
int i,j,k=0;
//getline();
for (i=0;i<nl;i++)
{
if (l[i].segcrossseg(u)==2)return 1;
if (l[i].segcrossseg(u)==1)k=1;
}
if (!k)return 0;
vector<point>vp;
for (i=0;i<nl;i++)
{
if (l[i].segcrossseg(u))
{
if (l[i].parallel(u))
{
vp.pb(u.a);
vp.pb(u.b);
vp.pb(l[i].a);
vp.pb(l[i].b);
continue;
}
vp.pb(l[i].crosspoint(u));
}
}
sort(vp.begin(),vp.end());
int sz=vp.size();
for (i=0;i<sz-1;i++)
{
point mid=vp[i].add(vp[i+1]).div(2);
if (relationpoint(mid)==1)return 1;
}
return 2;
*/
}; int k;
double X0,Y0;
line Line[];
struct poi
{
int x; int y;
}a[]; void xsort(int l,int r)
{
int i=l,j=r;
int mid=(l+r)/;
while(i<j)
{
while((a[i].x<a[mid].x)||((a[i].x==a[mid].x)&&(a[i].y<a[mid].y)))
i++;
while((a[j].x>a[mid].x)||((a[j].x==a[mid].x)&&(a[j].y>a[mid].y)))
j--;
if (i<=j)
{
swap(a[i].x,a[j].x);
swap(a[i].y,a[j].y);
i++; j--;
}
}
if (l<j) xsort(l,j);
if (i<r) xsort(i,r);
}
void ysort(int l,int r)
{
int i=l,j=r;
int mid=(l+r)/;
while(i<j)
{
while((a[i].y<a[mid].y)||((a[i].y==a[mid].y)&&(a[i].x<a[mid].x)))
i++;
while((a[j].y>a[mid].y)||((a[j].y==a[mid].y)&&(a[j].x>a[mid].x)))
j--;
if (i<=j)
{
swap(a[i].x,a[j].x);
swap(a[i].y,a[j].y);
i++; j--;
}
}
if (l<j) ysort(l,j);
if (i<r) ysort(i,r);
} bool cross(point a, point b, point c) {
//if ( ((a.y > c.y && b.y <= c.y) || (a.y <= c.y && b.y > c.y)) && c.x < a.x) {
if ( ( ( (dblcmp(a.y-c.y)==) && (dblcmp(b.y-c.y)!=) )||( (dblcmp(a.y-c.y)!=) && (dblcmp(b.y-c.y)==) ) ) && (dblcmp(c.x-a.x)==-) ) {
return true;
}
return false;
} int main()
{
while(cin>>k)
{
for (int i=;i<=k;i++)
cin>>a[i].x>>a[i].y; xsort(,k);
int NL=;
for (int i=;i<=k-;i=i+)
{
NL++;
Line[NL]=line(point(a[i].x,a[i].y),point(a[i+].x,a[i+].y));
//cout<<a[i].x<<","<<a[i].y<<" "<<a[i+1].x<<","<<a[i+1].y<<endl;
}
ysort(,k);
for (int i=;i<=k-;i=i+)
{
NL++;
Line[NL]=line(point(a[i].x,a[i].y),point(a[i+].x,a[i+].y));
//cout<<a[i].x<<","<<a[i].y<<" "<<a[i+1].x<<","<<a[i+1].y<<endl;
} cin>>X0>>Y0;
point des=point(X0,Y0);
int ans=,cnt=;
for (int i=;i<=NL;i++)
{
line tl=Line[i];
if (tl.pointonseg(des))
{
//cout<<i<<endl;
ans=;
}
if (cross(tl.a,tl.b,des))
{
cout<<i<<endl;
cnt++;
}
}
if (ans==)
cout<<"BORDER"<<endl;
else
{
if(cnt%==)
cout<<"OUTSIDE"<<endl;
else
cout<<"INSIDE"<<endl;
} /*
PY.n=k; PY.nl=NL;
for (int i=0;i<k;i++)
{
cout<<a[i+1].x<<","<<a[i+1].y<<endl;
PY.p[i]=point(a[i+1].x,a[i+1].y);
}
for (int i=0;i<NL;i++)
{
cout<<Line[i+1].a.x<<","<<Line[i+1].a.y<<"->"<<Line[i+1].b.x<<","<<Line[i+1].b.y<<endl;
PY.l[i]=Line[i+1];
} cin>>X0>>Y0;
int ans=PY.relationpoint(point(X0,Y0));
//3 点上
//2 边上
//1 内部
//0 外部
if (ans==1)
cout<<"INSIDE"<<endl;
else if (ans==0)
cout<<"OUTSIDE"<<endl;
else
cout<<"BORDER"<<endl;
*/
}
return ;
}
xcoj1062的更多相关文章
随机推荐
- ZooKeeper 笔记(2) 监听数据变化
ZK中的每个节点都可以存储一些轻量级的数据,这些数据的变化会同步到集群中的其它机器.在应用中程序员可以添加watcher来监听这些数据的变化,watcher只会触发一次,所以触发过后想要继续监听,必须 ...
- 开发备忘:AngularJS Syntax error, unrecognized expression in template file
在写基于Angular的项目过程中,运行 grunt test的时候,一直给我蹦出这个错误,导致我的test一直跑不过,怎么试都是失败,经过重复排查,发现是因为template file中的html元 ...
- 流形学习之等距特征映射(Isomap)
感觉是有很久没有回到博客园,发现自己辛苦写的博客都被别人不加转载的复制粘贴过去真的心塞,不过乐观如我,说明做了一点点东西,不至于太蠢,能帮人最好.回校做毕设,专心研究多流形学习方法,生出了考研的决心. ...
- SQLServer(MSSQL)、MySQL、SQLite、Access相互迁移转换工具 DB2DB v1.4
最近公司有一个项目,需要把原来的系统从 MSSQL 升迁到阿里云RDS(MySQL)上面.为便于测试,所以需要把原来系统的所有数据表以及测试数据转换到 MySQL 上面.在百度上找了很多方法,有通过微 ...
- SqlServer导入数据到MySql
1.下载MySql ODBC Driver并进行安装.例如我下载的这个安装包是mysql-connector-odbc-5.1.6-win32.msi. 2.装完后,添加odbc数据源: 3.在sql ...
- Javascript 模块化开发上线解决方案
最近又换部门了,好频繁地说...于是把这段时间搞的小工具们简单整理了一下,作了一个小的总结.这次用一个简单业务demo来向大家介绍一下Javascript模块化开发的方式和自动化合并压缩的一些自己的处 ...
- [CF#286 Div2 D]Mr. Kitayuta's Technology(结论题)
题目:http://codeforces.com/contest/505/problem/D 题目大意:就是给你一个n个点的图,然后你要在图中加入尽量少的有向边,满足所有要求(x,y),即从x可以走到 ...
- 基本数据类型-列表_元组_字典_day4
一.列表(list)书写格式:[] #通过list类创建的 li = [1, 12, 9, ", 10, ],"庞麦郎"], "ales", True ...
- jquery 获取Select option 选择的Text和Value
jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关设置 获取一组radio被选中项的值:var item = $(' ...
- iOS开发中的错误整理,IOS9中canOpenURL调用失败分析
由于IOS加入对用户隐私以及禁止扫描系统信息的控制,目前通过canOpenURL的方法来判断用户是否安装特定app,则会出现-canOpenURL: failed for URL: "ABC ...