Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define pb push_back
- #define mp make_pair
- #define sz(x) (int)(x).size()
- #define li long long
- #define ld long double
- #define x first
- #define y second
- #define pt pair<li, li>
- #define pll pair<ll, ll>
- #define forn(i, t) for(int i = 0; i < (t); i++)
- #define fore(i, f, t) for(int i = (f); i < (t); i++)
- #define forr(i, f, t) for(int i = (f) - 1; i >= (t); i--)
- #define all(x) (x).begin(), (x).end()
- #define ins insert
- using namespace std;
- const int INF = 1e9;
- const int MOD = 1e9 + 7;
- const li INF64 = 1e18;
- const ld EPS = 1e-7;
- mt19937 myrand(time(NULL));
- const int N = 53;
- int n, R;
- pt a[N];
- int b[N], d[N];
- int f[3 * N][3 * N];
- vector<int> cx, cy;
- pt pos[N][5];
- void upd(int x, int y){
- for (int i = x; i < 3 * N; i |= i + 1)
- for (int j = y; j < 3 * N; j |= j + 1)
- f[i][j]++;
- }
- int get(int x, int y){
- int sum = 0;
- for (int i = x; i >= 0; i = (i & (i + 1)) - 1)
- for (int j = y; j >= 0; j = (j & (j + 1)) - 1)
- sum += f[i][j];
- return sum;
- }
- pt operator -(const pt a, const pt b){
- return mp(a.x - b.x, a.y - b.y);
- }
- struct Circle{
- double x, y, r;
- Circle(pt a){
- x = a.x;
- y = a.y;
- r = 0.1;
- };
- Circle(pt a, pt b){
- x = (a.x + b.x) / 2.0;
- y = (a.y + b.y) / 2.0;
- r = hypot(a.x - b.x, a.y - b.y) / 2;
- };
- Circle(pt a, pt b, pt c){
- double d = 2.0 * (a.x * b.y + a.y * c.x + b.x * c.y - a.x * c.y - a.y * b.x - b.y * c.x);
- double aa = a.x * a.x + a.y * a.y, bb = b.x * b.x + b.y * b.y, cc = c.x * c.x + c.y * c.y;
- x = (aa * b.y + a.y * cc + bb * c.y - aa * c.y - a.y * bb - b.y * cc) * 1.0 / d;
- y = -(aa * b.x + a.x * cc + bb * c.x - aa * c.x - a.x * bb - b.x * cc) * 1.0 / d;
- r = (double)(hypotl(a.x - b.x, a.y - b.y) * hypotl(a.x - c.x, a.y - c.y) * hypotl(b.x - c.x, b.y - c.y) / ((b - a).x * (c - a).y - (b - a).y * (c - a).x) / 2);
- };
- Circle(){};
- };
- struct Line{
- double A, B, C;
- Line(pt a, pt b){
- A = b.y - a.y;
- B = a.x - b.x;
- C = -A * a.x - B * a.y;
- };
- Line(){};
- };
- bool isOn(pt a, Line l){
- return (l.A * a.x + l.B * a.y + l.C == 0);
- }
- bool read(){
- if(scanf("%d%d", &n, &R) != 2)
- return 0;
- forn(i, n)
- scanf("%lld%lld", &a[i].x, &a[i].y);
- return 1;
- }
- pt dt[4] = {{1, 1}, {-1,- 1}, {1, -1}, {-1, 1}};
- int check1(Line l){
- int cnt1 = 0, cnt2 = 0;
- forn(i, n)
- if (l.A * a[i].x + l.B * a[i].y + l.C < EPS)
- b[cnt1++] = i;
- else
- d[cnt2++] = i;
- /*forn(i, cnt1)
- printf("[%d %d] ", a[b[i]].x, a[b[i]].y);
- printf("\n");
- forn(i, cnt2)
- printf("[%d %d] ", a[d[i]].x, a[d[i]].y);
- printf("\n\n");*/
- memset(f, 0, sizeof(f));
- forn(i, cnt1)
- upd(pos[b[i]][0].x, pos[b[i]][0].y);
- int res1 = 0, res2 = 0;
- int x1, x2, y1, y2;
- int cur;
- forn(i, cnt1)
- fore(j, i + 1, cnt1)
- if ((a[b[i]].x > a[b[j]].x && a[b[i]].y < a[b[j]].y) || (a[b[i]].x < a[b[j]].x && a[b[i]].y > a[b[j]].y)){
- x1 = min(pos[b[i]][0].x, pos[b[j]][0].x);
- y1 = min(pos[b[i]][0].y, pos[b[j]][0].y);
- x2 = min(pos[b[i]][1].x, pos[b[j]][1].x);
- y2 = min(pos[b[i]][1].y, pos[b[j]][1].y);
- cur = get(x2, y2) - get(x1 - 1, y2) - get(x2, y1 - 1) + get(x1 - 1, y1 - 1);
- res1 = max(cur, res1);
- x1 = max(pos[b[i]][0].x, pos[b[j]][0].x);
- y1 = max(pos[b[i]][0].y, pos[b[j]][0].y);
- x2 = max(pos[b[i]][2].x, pos[b[j]][2].x);
- y2 = max(pos[b[i]][2].y, pos[b[j]][2].y);
- cur = get(x1, y1) - get(x2 - 1, y1) - get(x1, y2 - 1) + get(x2 - 1, y2 - 1);
- res1 = max(cur, res1);
- }
- else{
- x1 = min(pos[b[i]][0].x, pos[b[j]][0].x);
- y1 = max(pos[b[i]][0].y, pos[b[j]][0].y);
- x2 = min(pos[b[i]][1].x, pos[b[j]][1].x);
- y2 = max(pos[b[i]][2].y, pos[b[j]][2].y);
- cur = get(x2, y1) - get(x1 - 1, y1) - get(x2, y2 - 1) + get(x1 - 1, y2 - 1);
- res1 = max(cur, res1);
- x1 = max(pos[b[i]][0].x, pos[b[j]][0].x);
- y1 = min(pos[b[i]][0].y, pos[b[j]][0].y);
- x2 = max(pos[b[i]][2].x, pos[b[j]][2].x);
- y2 = min(pos[b[i]][1].y, pos[b[j]][1].y);
- cur = get(x1, y2) - get(x2 - 1, y2) - get(x1, y1 - 1) + get(x2 - 1, y1 - 1);
- res1 = max(cur, res1);
- }
- forn(i, cnt1){
- x1 = pos[b[i]][0].x;
- y1 = pos[b[i]][0].y;
- forn(j, 4){
- x2 = pos[b[i]][dt[j].x > 0 ? 1 : 2].x;
- y2 = pos[b[i]][dt[j].y > 0 ? 1 : 2].y;
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res1 = max(res1, cur);
- }
- }
- memset(f, 0, sizeof(f));
- forn(i, cnt2)
- upd(pos[d[i]][0].x, pos[d[i]][0].y);
- forn(i, cnt2)
- fore(j, i + 1, cnt2)
- if ((a[d[i]].x > a[d[j]].x && a[d[i]].y < a[d[j]].y) || (a[d[i]].x < a[d[j]].x && a[d[i]].y > a[d[j]].y)){
- x1 = min(pos[d[i]][0].x, pos[d[j]][0].x);
- y1 = min(pos[d[i]][0].y, pos[d[j]][0].y);
- x2 = min(pos[d[i]][1].x, pos[d[j]][1].x);
- y2 = min(pos[d[i]][1].y, pos[d[j]][1].y);
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(cur, res2);
- x1 = max(pos[d[i]][0].x, pos[d[j]][0].x);
- y1 = max(pos[d[i]][0].y, pos[d[j]][0].y);
- x2 = max(pos[d[i]][2].x, pos[d[j]][2].x);
- y2 = max(pos[d[i]][2].y, pos[d[j]][2].y);
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(cur, res2);
- }
- else{
- x1 = min(pos[d[i]][0].x, pos[d[j]][0].x);
- y1 = max(pos[d[i]][0].y, pos[d[j]][0].y);
- x2 = min(pos[d[i]][1].x, pos[d[j]][1].x);
- y2 = max(pos[d[i]][2].y, pos[d[j]][2].y);
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(cur, res2);
- x1 = max(pos[d[i]][0].x, pos[d[j]][0].x);
- y1 = min(pos[d[i]][0].y, pos[d[j]][0].y);
- x2 = max(pos[d[i]][2].x, pos[d[j]][2].x);
- y2 = min(pos[d[i]][1].y, pos[d[j]][1].y);
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(cur, res2);
- }
- forn(i, cnt2){
- x1 = pos[d[i]][0].x;
- y1 = pos[d[i]][0].y;
- forn(j, 4){
- x2 = pos[d[i]][dt[j].x > 0 ? 1 : 2].x;
- y2 = pos[d[i]][dt[j].y > 0 ? 1 : 2].y;
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(res2, cur);
- }
- }
- return res1 + res2;
- }
- int check2(Line l){
- int cnt1 = 0, cnt2 = 0;
- forn(i, n)
- if (l.A * a[i].x + l.B * a[i].y + l.C < -EPS)
- b[cnt1++] = i;
- else
- d[cnt2++] = i;
- /*forn(i, cnt1)
- printf("[%d %d] ", a[b[i]].x, a[b[i]].y);
- printf("\n");
- forn(i, cnt2)
- printf("[%d %d] ", a[d[i]].x, a[d[i]].y);
- printf("\n\n");*/
- memset(f, 0, sizeof(f));
- forn(i, cnt1)
- upd(pos[b[i]][0].x, pos[b[i]][0].y);
- int res1 = 0, res2 = 0;
- int x1, x2, y1, y2;
- int cur;
- forn(i, cnt1)
- fore(j, i + 1, cnt1)
- if ((a[b[i]].x > a[b[j]].x && a[b[i]].y < a[b[j]].y) || (a[b[i]].x < a[b[j]].x && a[b[i]].y > a[b[j]].y)){
- x1 = min(pos[b[i]][0].x, pos[b[j]][0].x);
- y1 = min(pos[b[i]][0].y, pos[b[j]][0].y);
- x2 = min(pos[b[i]][1].x, pos[b[j]][1].x);
- y2 = min(pos[b[i]][1].y, pos[b[j]][1].y);
- cur = get(x2, y2) - get(x1 - 1, y2) - get(x2, y1 - 1) + get(x1 - 1, y1 - 1);
- res1 = max(cur, res1);
- x1 = max(pos[b[i]][0].x, pos[b[j]][0].x);
- y1 = max(pos[b[i]][0].y, pos[b[j]][0].y);
- x2 = max(pos[b[i]][2].x, pos[b[j]][2].x);
- y2 = max(pos[b[i]][2].y, pos[b[j]][2].y);
- cur = get(x1, y1) - get(x2 - 1, y1) - get(x1, y2 - 1) + get(x2 - 1, y2 - 1);
- res1 = max(cur, res1);
- }
- else{
- x1 = min(pos[b[i]][0].x, pos[b[j]][0].x);
- y1 = max(pos[b[i]][0].y, pos[b[j]][0].y);
- x2 = min(pos[b[i]][1].x, pos[b[j]][1].x);
- y2 = max(pos[b[i]][2].y, pos[b[j]][2].y);
- cur = get(x2, y1) - get(x1 - 1, y1) - get(x2, y2 - 1) + get(x1 - 1, y2 - 1);
- res1 = max(cur, res1);
- x1 = max(pos[b[i]][0].x, pos[b[j]][0].x);
- y1 = min(pos[b[i]][0].y, pos[b[j]][0].y);
- x2 = max(pos[b[i]][2].x, pos[b[j]][2].x);
- y2 = min(pos[b[i]][1].y, pos[b[j]][1].y);
- cur = get(x1, y2) - get(x2 - 1, y2) - get(x1, y1 - 1) + get(x2 - 1, y1 - 1);
- res1 = max(cur, res1);
- }
- forn(i, cnt1){
- x1 = pos[b[i]][0].x;
- y1 = pos[b[i]][0].y;
- forn(j, 4){
- x2 = pos[b[i]][dt[j].x > 0 ? 1 : 2].x;
- y2 = pos[b[i]][dt[j].y > 0 ? 1 : 2].y;
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res1 = max(res1, cur);
- }
- }
- memset(f, 0, sizeof(f));
- forn(i, cnt2)
- upd(pos[d[i]][0].x, pos[d[i]][0].y);
- forn(i, cnt2)
- fore(j, i + 1, cnt2)
- if ((a[d[i]].x > a[d[j]].x && a[d[i]].y < a[d[j]].y) || (a[d[i]].x < a[d[j]].x && a[d[i]].y > a[d[j]].y)){
- x1 = min(pos[d[i]][0].x, pos[d[j]][0].x);
- y1 = min(pos[d[i]][0].y, pos[d[j]][0].y);
- x2 = min(pos[d[i]][1].x, pos[d[j]][1].x);
- y2 = min(pos[d[i]][1].y, pos[d[j]][1].y);
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(cur, res2);
- x1 = max(pos[d[i]][0].x, pos[d[j]][0].x);
- y1 = max(pos[d[i]][0].y, pos[d[j]][0].y);
- x2 = max(pos[d[i]][2].x, pos[d[j]][2].x);
- y2 = max(pos[d[i]][2].y, pos[d[j]][2].y);
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(cur, res2);
- }
- else{
- x1 = min(pos[d[i]][0].x, pos[d[j]][0].x);
- y1 = max(pos[d[i]][0].y, pos[d[j]][0].y);
- x2 = min(pos[d[i]][1].x, pos[d[j]][1].x);
- y2 = max(pos[d[i]][2].y, pos[d[j]][2].y);
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(cur, res2);
- x1 = max(pos[d[i]][0].x, pos[d[j]][0].x);
- y1 = min(pos[d[i]][0].y, pos[d[j]][0].y);
- x2 = max(pos[d[i]][2].x, pos[d[j]][2].x);
- y2 = min(pos[d[i]][1].y, pos[d[j]][1].y);
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(cur, res2);
- }
- forn(i, cnt2){
- x1 = pos[d[i]][0].x;
- y1 = pos[d[i]][0].y;
- forn(j, 4){
- x2 = pos[d[i]][dt[j].x > 0 ? 1 : 2].x;
- y2 = pos[d[i]][dt[j].y > 0 ? 1 : 2].y;
- cur = get(max(x1, x2), max(y1, y2)) -
- get(min(x1, x2) - 1, max(y1, y2)) -
- get(max(x1, x2), min(y1, y2) - 1) +
- get(min(x1, x2) - 1, min(y1, y2) - 1);
- res2 = max(res2, cur);
- }
- }
- return res1 + res2;
- }
- void solve(int num){
- int ans = (n == 1 ? 1 : 2);
- cx = cy = vector<int>();
- forn(i, n){
- cx.pb(a[i].x);
- cx.pb(a[i].x + R);
- cx.pb(a[i].x - R);
- cy.pb(a[i].y);
- cy.pb(a[i].y + R);
- cy.pb(a[i].y - R);
- }
- sort(all(cx));
- cx.resize(unique(all(cx)) - cx.begin());
- sort(all(cy));
- cy.resize(unique(all(cy)) - cy.begin());
- forn(i, n){
- pos[i][0] = mp(lower_bound(all(cx), a[i].x) - cx.begin(), lower_bound(all(cy), a[i].y) - cy.begin());
- pos[i][1] = mp(lower_bound(all(cx), a[i].x + R) - cx.begin(), lower_bound(all(cy), a[i].y + R) - cy.begin());
- pos[i][2] = mp(lower_bound(all(cx), a[i].x - R) - cx.begin(), lower_bound(all(cy), a[i].y - R) - cy.begin());
- }
- /*forn(i, n)
- ans = max(ans, check(Circle(a[i])));
- forn(i, n)
- fore(j, i + 1, n)
- ans = max(ans, check(Circle(a[i], a[j])));
- forn(i, n)
- fore(j, i + 1, n){
- Line l = Line(a[i], a[j]);
- fore(k, j + 1, n)
- if (!isOn(a[k], l))
- ans = max(ans, check(Circle(a[i], a[j], a[k])));
- }*/
- forn(i, n)
- fore(j, i + 1, n){
- ans = max(ans, check1(Line(a[i], a[j])));
- ans = max(ans, check2(Line(a[i], a[j])));
- }
- printf("Case #%d: ", num);
- printf("%d\n", ans);
- }
- int main(){
- #ifdef _DEBUG
- freopen("fighting_the_zombies.txt", "r", stdin);
- #endif
- int n;
- scanf("%d", &n);
- forn(i, n){
- read();
- solve(i + 1);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement