Submission #70474

#TimeUsernameProblemLanguageResultExecution timeMemory
70474ksun48The Forest of Fangorn (CEOI14_fangorn)C++14
50 / 100
3046 ms1220 KiB
#include <bits/stdc++.h> using namespace std; typedef long long LL; const double EPS = 1e-8; template <class T> struct Point { typedef Point P; T x, y; explicit Point(T x=0, T y=0) : x(x), y(y) {} bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); } bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); } P operator+(P p) const { return P(x+p.x, y+p.y); } P operator-(P p) const { return P(x-p.x, y-p.y); } P operator*(T d) const { return P(x*d, y*d); } P operator/(T d) const { return P(x/d, y/d); } T dot(P p) const { return x*p.x + y*p.y; } T cross(P p) const { return x*p.y - y*p.x; } T cross(P a, P b) const { return (a-*this).cross(b-*this); } T dist2() const { return x*x + y*y; } double dist() const { return sqrt((double)dist2()); } // angle to x-axis in interval [-pi, pi] double angle() const { return atan2(y, x); } P unit() const { return *this/dist(); } // makes dist()=1 P perp() const { return P(-y, x); } // rotates +90 degrees P normal() const { return perp().unit(); } // returns point rotated 'a' radians ccw around the origin P rotate(double a) const { return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); } }; template <class P> int lineIntersection(const P& s1, const P& e1, const P& s2, const P& e2, P& r) { if ((e1-s1).cross(e2-s2)) { //if not parallell r = s2-(e2-s2)*(e1-s1).cross(s2-s1)/(e1-s1).cross(e2-s2); return 1; } else return -((e1-s1).cross(s2-s1)==0 || s2==e2); } int main(){ LL w, h; cin >> w >> h; Point<double> start_point; cin >> start_point.x >> start_point.y; int c; cin >> c; vector<Point<double> > camps(c); for(int i = 0; i < c; i++){ cin >> camps[i].x >> camps[i].y; } int n; cin >> n; vector<Point<double> > trees(n); for(int i = 0; i < n; i++){ cin >> trees[i].x >> trees[i].y; } vector<Point<double> > ray_start, ray_end; for(int i = 0; i < n; i++){ // biggest, smallest angle(); int idx_min = -1; double angle_min; int idx_max = -1; double angle_max; for(int j = 0; j < n; j++){ if(i == j) continue; Point<double> diff_dir = trees[j] - trees[i]; Point<double> base_dir = start_point - trees[i]; double delta = Point<double>(1,0).rotate(diff_dir.angle() - base_dir.angle()).angle(); if(idx_min == -1 || delta < angle_min){ idx_min = j; angle_min = delta; } if(idx_max == -1 || delta > angle_max){ idx_max = j; angle_max = delta; } } ray_start.push_back(trees[i]); ray_end.push_back(trees[i] * 2 - trees[idx_min]); ray_start.push_back(trees[i]); ray_end.push_back(trees[i] * 2 - trees[idx_max]); } vector<int> ans; for(int i = 0; i < camps.size(); i++){ int ok = 1; // check to see if these are okay for(int a = 0; a < ray_start.size(); a++){ for(int b = 0; b < ray_start.size(); b++){ if(a == b) continue; Point<double> s1 = ray_start[a]; Point<double> e1 = ray_end[a]; Point<double> s2 = ray_start[b]; Point<double> e2 = ray_end[b]; Point<double> r; if(lineIntersection(s1, e1, s2, e2, r) != 1) continue; if((r-s1).dot(e1-s1) < -EPS || (r-s2).dot(e2-s2) < -EPS) continue; Point<double> sep1 = e1 - s1; Point<double> sep2 = e2 - s2; Point<double> ang1 = start_point - r; Point<double> ang2 = camps[i] - r; vector<pair<double, int> > f = {{sep1.angle(), 0}, {sep2.angle(), 0}, {ang1.angle(), 1}, {ang2.angle(), 1}}; sort(f.begin(), f.end()); if(f[0].second == f[2].second){ ok = 0; } } } if(ok) ans.push_back(i); } cout << ans.size() << '\n'; for(int x : ans){ cout << x + 1 << ' '; } cout << endl; }

Compilation message (stderr)

fangorn.cpp: In function 'int main()':
fangorn.cpp:87:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i = 0; i < camps.size(); i++){
                    ~~^~~~~~~~~~~~~~
fangorn.cpp:90:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int a = 0; a < ray_start.size(); a++){
                        ~~^~~~~~~~~~~~~~~~~~
fangorn.cpp:91:30: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             for(int b = 0; b < ray_start.size(); b++){
                            ~~^~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...