結果
問題 |
No.3154 convex polygon judge
|
ユーザー |
![]() |
提出日時 | 2025-05-20 21:25:31 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 73 ms / 2,000 ms |
コード長 | 6,621 bytes |
コンパイル時間 | 1,886 ms |
コンパイル使用メモリ | 207,824 KB |
実行使用メモリ | 15,864 KB |
最終ジャッジ日時 | 2025-05-20 21:25:39 |
合計ジャッジ時間 | 3,586 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 44 |
ソースコード
#include <bits/stdc++.h> using namespace std; typedef long long ll; template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; } template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; } #define vi vector<int> #define vl vector<ll> #define vii vector<pair<int,int>> #define vll vector<pair<ll,ll>> #define vvi vector<vector<int>> #define vvl vector<vector<ll>> #define vvii vector<vector<pair<int,int>>> #define vvll vector<vector<pair<ll,ll>>> #define vst vector<string> #define pii pair<int,int> #define pll pair<ll,ll> #define pb push_back #define all(x) (x).begin(),(x).end() #define mkunique(x) sort(all(x));(x).erase(unique(all(x)),(x).end()) #define fi first #define se second #define mp make_pair #define si(x) int(x.size()) const int mod=998244353,MAX=300005,INF=15<<26; //幾何ライブラリ(整数) class Point{ public: ll x,y; Point(ll x=0,ll y=0):x(x),y(y){} Point operator + (Point p){return Point(x+p.x,y+p.y);} Point operator - (Point p){return Point(x-p.x,y-p.y);} Point operator * (ll a){return Point(a*x,a*y);} double norm(){return x*x+y*y;} bool operator < (const Point &p)const{ return x<p.x||(x==p.x&&y<p.y); } bool operator == (const Point &p)const{ return x==p.x&&y==p.y; } }; typedef Point Vector; ll norm(Vector a){ return a.x*a.x+a.y*a.y; } ll dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; } ll cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; } struct Segment{ Point p1,p2; }; bool isOrthogonal(Vector a,Vector b){ return dot(a,b)==0; } bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){ return isOrthogonal(a1-a2,b1-b2); } bool isOrthogonal(Segment s1,Segment s2){ return dot(s1.p2-s1.p1,s2.p2-s2.p1)==0; } bool isParallel(Vector a,Vector b){ return cross(a,b)==0; } bool isParallel(Point a1,Point a2,Point b1,Point b2){ return isParallel(a1-a2,b1-b2); } bool isParallel(Segment s1,Segment s2){ return cross(s1.p2-s1.p1,s2.p2-s2.p1)==0; } //p0,p1,p2の順に見たときどうなるか? static const int counter_clockwise=1; static const int clockwise=-1; static const int online_back=2; static const int online_front=-2; static const int on_segment=0; int ccw(Point p0,Point p1,Point p2){ Vector a=p1-p0; Vector b=p2-p0; if(cross(a,b)>0) return counter_clockwise; if(cross(a,b)<0) return clockwise; if(dot(a,b)<0) return online_back; if(a.norm()<b.norm()) return online_front; return on_segment; } bool intersect(Point p1,Point p2,Point p3,Point p4){ return(ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0&&ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0); } bool intersect(Segment s1,Segment s2){ return intersect(s1.p1,s1.p2,s2.p1,s2.p2); } bool overlap(Segment s1,Segment s2){ int a=ccw(s1.p1,s1.p2,s2.p1),b=ccw(s1.p1,s1.p2,s2.p2); if(a&1||b&1) return 0; if(a==2){ if(b==-2||(b==0&&!(s2.p2==s1.p1))) return 1; else return 0; } if(a==-2){ if(b==2||(b==0&&!(s2.p2==s1.p2))) return 1; else return 0; } if(a==0){ if(s1.p1==s2.p1){ if(b!=2) return 1; else return 0; } else if(s1.p2==s2.p1){ if(b!=-2) return 1; else return 0; } else return 1; } return 0; } //s1とs2の共通の線分(長さ0より大きい)があるかどうか typedef Segment Line; //ネットの適当を書いたのであってるか全く知りません→あってそう class Circle{ public: Point c; ll r; Circle(Point c=Point(),ll r=0.0):c(c),r(r){} }; typedef vector<Point> Polygon; /* IN 2 ON 1 OUT 0 */ int contains(Polygon g,Point p){ int n=int(g.size()); bool x=false; for(int i=0;i<n;i++){ Point a=g[i]-p,b=g[(i+1)%n]-p; if(a.y>b.y) swap(a,b); if(a.y<=0&&0<b.y&&cross(a,b)<0) x=!x; if(abs(cross(a,b))<=0&&dot(a,b)<=0) return 1; } return (x?2:0); } //ayasii Polygon andrewScan(Polygon s,bool ok){ Polygon u,l; sort(all(s)); if(int(s.size())<3) return s; int n=int(s.size()); u.push_back(s[0]); u.push_back(s[1]); l.push_back(s[n-1]); l.push_back(s[n-2]); if(ok){ for(int i=2;i<n;i++){ for(int j=int(u.size());j>=2&&ccw(u[j-2],u[j-1],s[i])==counter_clockwise;j--){ u.pop_back(); } u.push_back(s[i]); } for(int i=int(s.size())-3;i>=0;i--){ for(int j=int(l.size());j>=2&&ccw(l[j-2],l[j-1],s[i])==counter_clockwise;j--){ l.pop_back(); } l.push_back(s[i]); } } if(!ok){ for(int i=2;i<n;i++){ for(int j=int(u.size());j>=2&&ccw(u[j-2],u[j-1],s[i])!=clockwise;j--){ u.pop_back(); } u.push_back(s[i]); } for(int i=int(s.size())-3;i>=0;i--){ for(int j=int(l.size());j>=2&&ccw(l[j-2],l[j-1],s[i])!=clockwise;j--){ l.pop_back(); } l.push_back(s[i]); } } reverse(all(l)); for(int i=int(u.size())-2;i>=1;i--) l.push_back(u[i]); return l; }//ok==1なら辺の上も含める ll area(Polygon P){ ll sum=0; for(int i=0;i<si(P);i++){ sum+=cross(P[i],P[(i+1)%si(P)]); } return abs(sum); } // 倍 ll gcd(ll a,ll b){ if(b==0) return a; return gcd(b,a%b); } pair<Point,Vector> perpendicular_bisector(Point a,Point b){ Point c; c.x=(a.x+b.x)/2; c.y=(a.y+b.y)/2; Vector v=b-c; swap(v.x,v.y); v.x*=-1; Point p=c; if(v.x==0){ v.y=1; p.y=0; } else if(v.y==0){ v.x=1; p.x=0; } else{ if(v.x<0){ v.x*=-1; v.y*=-1; } ll g=gcd(abs(ll(v.x)),abs(ll(v.y))); v.x/=g; v.y/=g; if(p.x>=0){ ll d=p.x/v.x; p=p-v*d; }else{ ll d=abs(p.x)/v.x; p=p+v*d; if(p.x<0){ p=p+v; } } } return mp(p,v); } //2倍するなりして整数にしておくこと int main(){ std::ifstream in("text.txt"); std::cin.rdbuf(in.rdbuf()); cin.tie(0); ios::sync_with_stdio(false); int N;cin>>N; vector<Point> P(N); for(int i=0;i<N;i++){ cin>>P[i].x>>P[i].y; } auto Q=andrewScan(P,0); if(si(Q)==N) cout<<"Yes\n"; else cout<<"No\n"; }