Submission #220384

# Submission time Handle Problem Language Result Execution time Memory
220384 2020-04-07T19:13:43 Z toxic_hack Park (BOI16_park) C++14
0 / 100
625 ms 66204 KB
// g++ -std=c++14

/*

Today might be the chance to grasp the chance to let your talent bloom.
May be tomorrow, the day after, or next year...
May be even when you are 30. I'm not sure if physique has anything to do with it
but if you think that it will never come, it probably never will.

- Tooru Oikawa.

*/


#include<bits/stdc++.h>

typedef long long ll;
typedef long double lld;
using namespace std;

#define endl "\n"
#define fi first
#define se second
#define MEMS(a,b) memset(a,b,sizeof(a))
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __ freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
#define all(c) c.begin(),c.end()
#define pii pair<int, int>

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rand(int l, int r)
{
	uniform_int_distribution<int> uid(l, r);
	return uid(rng);
}

#define tr(...) cout<<__FUNCTION__<<' '<<__LINE__<<" = ";trace(#__VA_ARGS__, __VA_ARGS__)
template<typename S, typename T>
ostream& operator<<(ostream& out,pair<S,T> const& p){out<<'('<<p.fi<<", "<<p.se<<')';return out;}

template<typename T>
ostream& operator<<(ostream& out,vector<T> const& v){
ll l=v.size();for(ll i=0;i<l-1;i++)out<<v[i]<<' ';if(l>0)out<<v[l-1];return out;}

template <typename T>
ostream &operator<<(ostream &out, set<T> const &v) {
    for (auto i = v.begin(); i != v.end(); i++)
        out << (*i) << ' ';
    return out;
}
template <typename T>
ostream &operator<<(ostream &out, multiset<T> const &v) {
    for (auto i = v.begin(); i != v.end(); i++)
        out << (*i) << ' ';
    return out;
}
template <typename T, typename V>
ostream &operator<<(ostream &out, map<T, V> const &v) {
    for (auto i = v.begin(); i != v.end(); i++)
        out << "\n" << (i->first) <<  ":"  << (i->second);
    return out;
}

template<typename T>
void trace(const char* name, T&& arg1){cout<<name<<" : "<<arg1<<endl;}

template<typename T, typename... Args>
void trace(const char* names, T&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ',');cout.write(names, comma-names)<<" : "<<arg1<<" | ";trace(comma+1,args...);}

#define int ll
const long double eps = 1e-12;
const long double infl = 1e20;

template <class T>
inline int sgn(const T & x) {
	return (x > eps) - (x < -eps);
}
template <class T>
struct Point {
 	T x, y;

	Point() : x(0), y(0) {

	}

	Point(const T & x, const T & y) : x(x), y(y) {

	}

	long double length() const {
		return sqrtl(x * x + y * y);
	}

	T length2() const {
		return x * x + y * y;
	}

	long double distance(const Point & rhs) const {
		return (rhs - *this).length();
	}

 	T cross(const Point & lhs, const Point & rhs) const {
		return (lhs - *this) * (rhs - *this);
	}

	T dot(const Point & lhs, const Point & rhs) const {
		return (lhs - *this) & (rhs - *this);
	}

	long double distance_to_line(const Point & p, const Point & q) const {
		if (p == q) return distance(p);
		else return fabsl(cross(p, q) / p.distance(q));
	}

	long double distance_to_segment(const Point & p, const Point & q) const {
		if (p == q) return distance(p);
		else if (p.dot(q, *this) < 0) return distance(p);
		else if (q.dot(p, *this) < 0) return distance(q);
		else return distance_to_line(p, q);
	}

	bool on_line(const Point & p, const Point & q) const {
		return sgn(cross(p, q)) == 0;
	}

	bool on_halfline(const Point & p, const Point & q, const bool & inclusive = true) const {
		if (*this == p) return inclusive;
		else return on_line(p, q) && sgn(p.dot(q, *this)) >= 0;
	}

	bool on_segment(const Point & p, const Point & q, const bool & inclusive = true) const {
		if (*this == p || *this == q) return inclusive;
		else return on_line(p, q) && sgn(dot(p, q)) <= 0;
	}

	bool in_triangle(const Point & u, const Point & v, const Point & w, const bool & inclusive = true) const {
		Point p[3] = {u, v, w};
		if (sgn(u.cross(v, w)) < 0) reverse(p, p + 3);
		for (int i = 0; i < 3; i++) {
			if (on_segment(p[i], p[(i + 1) % 3])) return inclusive;
			else if (sgn(cross(p[i], p[(i + 1) % 3])) < 0) return false;
		}
		return true;
	}

	bool in_angle(const Point & o, const Point & p, const Point & q, const bool & inclusive = true) const {
		if (on_halfline(o, p) || on_halfline(o, q)) return inclusive;
		int vs = sgn(o.cross(p, q)), ss = sgn(o.dot(p, q));
		if (vs == 0 && ss > 0) return false;
		int vp = sgn(o.cross(p, *this)), vq = sgn(o.cross(*this, q));
		if (sgn(o.cross(p, q)) >= 0) return vp > 0 && vq > 0;
		else return vp > 0 || vq > 0;
	}

	Point operator + (const Point & rhs) const {// returns a+b(vector addition)
		return Point(x + rhs.x, y + rhs.y);
	}

	Point operator - (const Point & rhs) const {// Returns a-b(vector subtraction)
		return Point(x - rhs.x, y - rhs.y);
	}

	T operator * (const Point & rhs) const { 	// cross product
		return x * rhs.y - y * rhs.x;
	}

	T operator & (const Point & rhs) const { 	// dot product
		return x * rhs.x + y * rhs.y;
	}

	Point operator * (const T & rhs) const {	// multiplication with constant
		return Point(x * rhs, y * rhs);
	}

	Point operator / (const T & rhs) const {	// division with constant
		return Point(x / rhs, y / rhs);
	}

	bool operator == (const Point & rhs) const {// returns true if points are located at the same point.
		return x == rhs.x && y == rhs.y;
	}

	bool operator != (const Point & rhs) const {// returns true if points are not located at same point.
		return x != rhs.x || y != rhs.y;
	}

	inline int quadrant() const {				// returns quadrant defined from 0 to 7 (-1 if origin). Used in operator <
		if (x == 0 && y == 0) return -1;
		else if (x < 0 && y < 0) return 0;
		else if (x == 0 && y < 0) return 1;
		else if (x > 0 && y < 0) return 2;
		else if (x > 0 && y == 0) return 3;
		else if (x > 0 && y > 0) return 4;
		else if (x == 0 && y > 0) return 5;
		else if (x < 0 && y > 0) return 6;
		else return 7;
	}

	bool operator < (const Point & rhs) const {	//used for sorting the points in counter clockwise order.
		int lq = quadrant(), rq = rhs.quadrant();
		if (lq != rq) {
			return lq < rq;
		} else {
			int s = sgn(*this * rhs);
			return s != 0 ? s > 0 : sgn(length2() - rhs.length2()) < 0;
		}
	}
};
const int N = 2200;

struct circle {
    int x, y, r;
};
int n, m, w, h;
vector<circle> arr;

int sq(int x) {return x * x;}

lld pdist(pii a, pii b) {
    return sqrtl(sq(a.fi - b.fi) + sq(a.se - b.se));
}

lld get_dist(int i, int j) {
    lld tot = pdist({arr[i].x, arr[i].y}, {arr[j].x, arr[j].y});
    tot -= arr[i].r;
    tot -= arr[j].r;
    return tot;
}

int parent[N];
int size[N];

void make_set(int x) {
    parent[x] = x;
    size[x] = 1;
}

int find_set(int v) {
    if(v == parent[v]) {
        return v;
    }
    return parent[v] = find_set(parent[v]);
}

void union_sets(int a, int b) {
    a = find_set(a);
    b = find_set(b);
    if(a != b) {
        if(size[a] < size[b]) {
            swap(a,b);
        }
        parent[b] = a;
        size[a] += size[b];
    }
}


int solve() {
    cin >> n >> m >> w >> h;
    for (int i = 0; i < n; i++) {
        int x, y, r;
        cin >> x >> y >> r;
        arr.push_back({x, y, r});
    }

    vector<pair<lld, pii>> edges;

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            auto dist = get_dist(i, j);
            edges.push_back({dist, {i + 1, j + 1}});
            // tr(i, j, dist);
        }
    }
    Point<lld> lb, rb, lt, rt;
    lb.x = 0, lb.y = 0;
    rb.x = w, rb.y = 0;
    lt.x = 0, lt.y = h;
    rt.x = w, rt.y = h;
    vector<pair<Point<lld>, Point<lld>>> corners = {{lb, lt}, {lb, rb}, {rt, rb}, {lt, rt}} ;
    for (int i = 0; i < n; i++) {
        Point<lld> p;
        p.x = arr[i].x;
        p.y = arr[i].y;
        for (int j = 0; j < 4; j++) {
            lld dist = p.distance_to_line(corners[j].first, corners[j].second);
            edges.push_back({dist, {i + 1, n + 1 + j}});
            // tr(i, j, edges.back());
        }
    }

    for (int i = 1; i <= n + 4; i++) {
        make_set(i);
    }

    vector<vector<lld>> mat(4, vector<lld> (4, -1.0));

    sort(all(edges));
    // tr(edges);
    lld curr = 0.0;
    for (auto &e : edges) {
        curr = e.first;
        union_sets(e.second.first, e.second.second);
        for (int i = 0; i < 4; i++) {
            for (int j = i + 1; j < 4; j++) {
                int x = find_set(n + i + 1);
                int y = find_set(n + j + 1);
                if (x == y && (mat[i][j] < 0)) {
                    // tr(i, j, curr);
                    mat[i][j] = curr;
                    mat[j][i] = curr;
                }
            }
        }
    }
    // for(int i = 0; i < 4; i++) {
    //     for (int j = 0; j < 4; j++) {
    //         cout << mat[i][j] << " ";
    //     }
    //     cout << endl;
    // }
    // cout << endl;

    for (int i_ = 0; i_ < m; i_++) {
        int rad, pos;
        cin >> rad >> pos;
        rad *= 2;
        pos--;
        string ans = "";
        lld req = 1e10;
        if (pos == 0) {
            if (rad <= min({mat[0][3], mat[0][2], mat[0][1]})) {
                ans += '4';
            }
            if (rad <= min({mat[0][3], mat[3][2], mat[0][1]})) {
                ans += '3';
            }
            if (rad <= min({mat[1][2], mat[3][1], mat[0][1]})) {
                ans += '2';
            }
            ans += '1';
        } else if (pos == 1) {
            if (rad <= min({mat[1][2], mat[3][1], mat[0][1]})) {
                ans += '1';
            }
            if (rad <= min({mat[1][2], mat[3][2], mat[0][2]})) {
                ans += '3';
            }
            if (rad <= min({mat[1][2], mat[3][0], mat[0][2]})) {
                ans += '4';
            }
            ans += '2';
        } else if (pos == 2) {
            if (rad <= min({mat[0][3], mat[3][2], mat[0][1]})) {
                ans += '1';
            }
            if (rad <= min({mat[1][2], mat[3][2], mat[0][2]})) {
                ans += '2';
            }
            if (rad <= min({mat[1][3], mat[3][2], mat[0][3]})) {
                ans += '4';
            }
            ans += '3';
        } else {
            if (rad <= min({mat[0][3], mat[0][2], mat[0][1]})) {
                ans += '1';
            }
            if (rad <= min({mat[1][2], mat[3][0], mat[0][2]})) {
                ans += '2';
            }
            if (rad <= min({mat[1][3], mat[3][2], mat[0][3]})) {
                ans += '3';
            }
            ans += '4';
        }
        sort(all(ans));
        cout << ans << endl;
    }

}

int32_t main(){ _
    int t;
    // cin >> t;
    t = 1;
    while (t--) solve();
}

Compilation message

park.cpp: In function 'll solve()':
park.cpp:331:13: warning: unused variable 'req' [-Wunused-variable]
         lld req = 1e10;
             ^~~
park.cpp:381:1: warning: no return statement in function returning non-void [-Wreturn-type]
 }
 ^
# Verdict Execution time Memory Grader output
1 Correct 620 ms 66204 KB Output is correct
2 Incorrect 625 ms 66200 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 42 ms 2676 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 620 ms 66204 KB Output is correct
2 Incorrect 625 ms 66200 KB Output isn't correct
3 Halted 0 ms 0 KB -