結果

問題 No.2355 Unhappy Back Dance
ユーザー RubikunRubikun
提出日時 2023-06-16 21:44:59
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 608 ms / 6,000 ms
コード長 6,714 bytes
コンパイル時間 3,045 ms
コンパイル使用メモリ 225,628 KB
実行使用メモリ 4,380 KB
最終ジャッジ日時 2023-09-06 19:10:32
合計ジャッジ時間 15,405 ms
ジャッジサーバーID
(参考情報)
judge11 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,376 KB
testcase_01 AC 2 ms
4,376 KB
testcase_02 AC 2 ms
4,380 KB
testcase_03 AC 1 ms
4,380 KB
testcase_04 AC 2 ms
4,376 KB
testcase_05 AC 1 ms
4,376 KB
testcase_06 AC 435 ms
4,376 KB
testcase_07 AC 448 ms
4,376 KB
testcase_08 AC 429 ms
4,376 KB
testcase_09 AC 430 ms
4,376 KB
testcase_10 AC 501 ms
4,376 KB
testcase_11 AC 499 ms
4,376 KB
testcase_12 AC 458 ms
4,380 KB
testcase_13 AC 457 ms
4,376 KB
testcase_14 AC 515 ms
4,376 KB
testcase_15 AC 1 ms
4,380 KB
testcase_16 AC 608 ms
4,376 KB
testcase_17 AC 605 ms
4,376 KB
testcase_18 AC 602 ms
4,376 KB
testcase_19 AC 595 ms
4,380 KB
testcase_20 AC 597 ms
4,376 KB
testcase_21 AC 220 ms
4,376 KB
testcase_22 AC 31 ms
4,376 KB
testcase_23 AC 34 ms
4,376 KB
testcase_24 AC 534 ms
4,380 KB
testcase_25 AC 301 ms
4,380 KB
testcase_26 AC 299 ms
4,380 KB
testcase_27 AC 220 ms
4,376 KB
testcase_28 AC 5 ms
4,376 KB
testcase_29 AC 9 ms
4,376 KB
testcase_30 AC 501 ms
4,376 KB
testcase_31 AC 374 ms
4,376 KB
testcase_32 AC 25 ms
4,380 KB
testcase_33 AC 180 ms
4,380 KB
testcase_34 AC 2 ms
4,376 KB
testcase_35 AC 6 ms
4,380 KB
testcase_36 AC 223 ms
4,376 KB
testcase_37 AC 119 ms
4,380 KB
testcase_38 AC 142 ms
4,380 KB
testcase_39 AC 114 ms
4,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
typedef __int128_t 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 all(x) (x).begin(),(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=1<<30;

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

//int128

//https://kopricky.github.io/code/Misc/int128.html

// __int128の入出力

using LL = __int128;
istream& operator>>(istream& is, LL& v)
{
    string s;
    is >> s;
    v = 0;
    for (int i = 0; i < (int)s.size(); i++) {
        if (isdigit(s[i])) { v = v * 10 + s[i] - '0'; }
    }
    if (s[0] == '-') { v *= -1; }
    return is;
}

ostream& operator<<(ostream& os, const LL& v)
{
    if (v == 0) { return (os << "0"); }
    LL num = v;
    if (v < 0) {
        os << '-';
        num = -num;
    }
    string s;
    for (; num > 0; num /= 10) { s.push_back((char)(num % 10) + '0'); }
    reverse(s.begin(), s.end());
    return (os << s);
}



//幾何ライブラリ(整数)

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
 */


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 gcd(ll a,ll b){
    if(b==0) return a;
    return gcd(b,a%b);
}
//2倍するなりして整数にしておくこと

bool compare(pair<Point,int> a,pair<Point,int> b){
    int at,bt;
    if(a.fi.y>0||(a.fi.y==0&&a.fi.x>0)) at=0;
    else at=1;
    
    if(b.fi.y>0||(b.fi.y==0&&b.fi.x>0)) bt=0;
    else bt=1;
    
    if(at!=bt) return at<bt;
    return a.fi.x*b.fi.y-a.fi.y*b.fi.x>0;
}

//整数での偏角ソート [0,2pi)になる

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;
    
    vector<int> OK(N);
    for(int i=0;i<N;i++){
        vector<pair<Point,int>> Q;
        for(int j=0;j<N;j++){
            if(i==j) continue;
            Q.push_back(mp(P[j]-P[i],j));
        }
        sort(all(Q),compare);
        for(int j=0;j<N-1;j++) Q.push_back(Q[j]);
        int k=0;
        for(int j=0;j<N-1;j++){
            while(k-j<N-1){
                ll x=ccw(P[Q[j].se],P[i],P[Q[k].se]);
                if(x==-2){
                    OK[Q[j].se]=OK[Q[k].se]=true;
                    break;
                }
                if(x==1) break;
                k++;
            }
        }
    }
    int ans=0;
    for(int i=0;i<N;i++) ans+=OK[i];
    
    cout<<ans<<endl;
}
0