UVa 10535 - Shooter (最多区间覆盖的点 + 扫描)

题意

问一枪能最多能崩掉几堵墙

思路

求出墙和人的角度,一枪能崩掉这个角度里的墙,问题就转化成被覆盖最多的角度。

用左端点和右端点扫描。书上例题

因为对弧度不熟悉,所以转化为角度。。

如果相差大于180度,要分成[0, a][b, 360]。

代码

#include <stack>
#include <cstdio>
#include <list>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <functional>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <string>
#include <map>
#include <cmath>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define SZ(x) (int)x.size()
#define Lowbit(x) ((x) & (-x))
#define MP(a, b) make_pair(a, b)
#define MS(arr, num) memset(arr, num, sizeof(arr))
#define PB push_back
#define X first
#define Y second
#define ROP freopen("input.txt", "r", stdin);
#define MID(a, b) (a + ((b - a) >> 1))
#define LC rt << 1, l, mid
#define RC rt << 1|1, mid + 1, r
#define LRT rt << 1
#define RRT rt << 1|1
#define BitCount(x) __builtin_popcount(x)
#define BitCountll(x) __builtin_popcountll(x)
#define LeftPos(x) 32 - __builtin_clz(x) - 1
#define LeftPosll(x) 64 - __builtin_clzll(x) - 1
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int MAXN = 1e3 + 10;
const int MOD = 29;
const int dir[][2] = { {1, 0}, {0, 1} };
int cases = 0;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
 
struct LINE
{
    pdd l, r;
}L[MAXN];
 
vector<pair<double, int> > range;
pdd pos;
int n;
 
void Convert()
{
    range.clear();
    for (int i = 0; i < n; i++)
    {
        LINE tmp = L[i];
        double a = atan2(tmp.l.Y - pos.Y, tmp.l.X - pos.X) * 180 / PI, b = atan2(tmp.r.Y - pos.Y, tmp.r.X - pos.X) * 180 / PI;
        if (a < 0) a += 360;
        if (b < 0) b += 360;
        if (a > b) swap(a, b);
        if (b - a >= 180)
        {
            range.PB({0, 1}); range.PB({a, -1});
            a = b; b = 360;
        }
        range.PB({a, 1}); range.PB({b, -1});
    }
}
 
int cmp(pair<double, int> a, pair<double, int> b)
{
    if (fabs(a.X - b.X) > eps) return a.X < b.X;
    return a.Y > b.Y;
}
 
int main()
{
    //ROP;
    while (cin >> n, n)
    {
        for (int i = 0; i < n; i++) cin >> L[i].l.X >> L[i].l.Y >> L[i].r.X >> L[i].r.Y;
        cin >> pos.X >> pos.Y;
        Convert();
        sort(range.begin(), range.end(), cmp);
        int tmp = 0, ans = -1;
        for (int i = 0; i < SZ(range); i++)
        {
            tmp += range[i].Y;
            ans = max(ans, tmp);
        }
        cout << ans << endl;
    }
    return 0;
}

Powered by Jekyll and Theme by solid