제출 #260451

#제출 시각아이디문제언어결과실행 시간메모리
260451georgerapeanuPrinted Circuit Board (CEOI12_circuit)C++11
45 / 100
143 ms8900 KiB
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>

using namespace std;

int n;
pair<int,int> p[100005];
int ord[100005];
bool seen[100005];

const pair<int,int> origin = make_pair(0,0);

long long det(const pair<int,int> &a,const pair<int,int> &b,const pair<int,int> &c){
    return 1LL * a.first * (b.second - c.second) + 1LL * b.first * (c.second - a.second) + 1LL * c.first * (a.second - b.second);
}

pair<int,int> dir;
pair<int,int> nxt_dir;

struct segm_t{
    int i,j;
    long long a,b,c;

    segm_t(int i,int j){
        this->i = i;
        this->j = j;
        a = p[j].second - p[i].second;
        b = p[i].first - p[j].first;
        c = 1LL * p[j].first * p[i].second - 1LL * p[i].first * p[j].second;
    }

    bool operator < (const segm_t &other)const{
        ///-c/(a * dir.first + b * dir.second) < -other.c / (other.a * dir.first + other.b * dir.second);
        int sgn = (a * dir.first + b * dir.second > 0 ? 1:-1) * (other.a * dir.first + other.b * dir.second > 0 ? 1:-1);
        long long fst = sgn * c * (other.a * dir.first + other.b * dir.second);
        long long snd = sgn * other.c * (a * dir.first + b * dir.second);
        if(fst != snd){
            return fst > snd;
        }
        else{
            pair<int,int> dir = nxt_dir;
            int sgn = (a * dir.first + b * dir.second > 0 ? 1:-1) * (other.a * dir.first + other.b * dir.second > 0 ? 1:-1);
            long long fst = sgn * c * (other.a * dir.first + other.b * dir.second);
            long long snd = sgn * other.c * (a * dir.first + b * dir.second);
            if(fst != snd){
                return fst > snd;
            }
            else{
                return 1LL * p[j].second * p[j].second + 1LL * p[j].first * p[j].first < 1LL * p[other.j].first * p[other.j].first + 1LL * p[other.j].second * p[other.j].second;
            }
        }
    }

    bool is_good(const int &point)const{
        return det(p[i],p[j],p[point]) >= 0;
    }
};

set<segm_t> s;

bool cmp(const int &a,const int &b){
    return det(origin,p[a],p[b]) > 0;
}

int main(){

    scanf("%d",&n);

    for(int i = 1;i <= n;i++){
        scanf("%d %d",&p[i].first,&p[i].second);
        ord[i] = i;
    }

    sort(ord + 1,ord + 1 + n,cmp);

    vector<int> ans;


    for(int i = 1;i <= n;i++){
        dir = p[ord[i]];
        int j = i + 1;
        while(j <= n && cmp(ord[i],ord[j]) == 0){
            j++;
        }
        j--;
        nxt_dir = p[ord[j + 1]];
        for(int k = i;k <= j;k++){
            int curr = ord[k];
            int ant = (curr == 1 ? n:curr - 1);
            int nxt = (curr == n ? 1:curr + 1);
            ///TODO check colinearity of curr,nxt,ant to not erase stuff twice or smth            
            if(det(origin,p[curr],p[ant]) == 0){
                ;
            }
            else if(seen[ant]){
                s.erase(segm_t(ant,curr));
            }
            else{
                s.insert(segm_t(curr,ant));
            }
            if(det(origin,p[curr],p[nxt]) == 0){
                ;
            }
            else if(seen[nxt]){
                s.erase(segm_t(nxt,curr));
            }
            else{
                s.insert(segm_t(curr,nxt));
            }
        }

        int closest = -1;

        for(int k = i;k <= j;k++){
            if(closest == -1 || p[ord[k]].first < p[closest].first){
               closest = ord[k];  
            }
        }

        if(s.empty() == true){
            ans.push_back(closest);
        }
        else{
            if(s.begin()->is_good(closest)){
                ans.push_back(closest);
            }
        }

        for(int k = i;k <= j;k++){
            seen[ord[k]] = true;
        }
        i = j;
    }

    printf("%d\n",(int)ans.size());
   
    sort(ans.begin(),ans.end());

    for(auto it:ans){
        printf("%d ",it);
    }

    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

circuit.cpp: In function 'int main()':
circuit.cpp:69:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d",&n);
     ~~~~~^~~~~~~~~
circuit.cpp:72:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d %d",&p[i].first,&p[i].second);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...