貪欲なEレーダーのインストール

E-レーダーの設置

トピックリンク:E-Radarのインストール
ここに写真の説明を挿入

回答

アイデア

このトピックでは、すべての島をカバーできるレーダーの最小数を見つける必要があります。
レーダーは特定の範囲をカバーできるため、カバーされる島の重要な条件は、島がレーダー検出範囲の境界上にあることです。つまり、島は頂点であり、レーダー検出半径はウエストであり、x軸は下、結果のアイソセル三角形。
すべての島はそのようなアイソセル三角形を得ることができます。等速線の三角形とx軸の交点から、島を覆うレーダーが配置されている間隔を取得できます。

得られた間隔a [x、y]、b [xx、yy]の場合、次の状況が存在する可能性があります。

  1. b間隔が間隔内にある。
  2. b間隔は間隔と同じです。
  3. b間隔と間隔の間にクロスがあります。
  4. b間隔と間隔の間に交差はありません。
  5. b間隔は間隔に隣接しています。
  6. 間隔aは間隔b内にあります。

上記のケースのうち、4番目のケースのみが新しいレーダーを追加する必要があります。

成し遂げる

上記の6つの判断がすべての間隔と他のすべての間隔に対して行われる場合、時間の複雑さは非常に大きくなります。
最初にすべての島のx座標を昇順で並べ替えることができるため、すべての島の間隔は次の状況になります。

ソートされた間隔アイランドa [x、y]、アイランドb [xx、yy]の場合(aはbの左側にあります):

  1. bはa内にあります。
  2. bはaと交差しています(bの左側の境界はaの間隔内にあります)。
  3. bにはaとの交差はありません。
  4. bおよびaの右側の境界点と交差します。
  5. bはaと同じです。

削減されるケースは1つだけのようですが、実際には上記の複数のケースを組み合わせることができ、並べ替えのため、左の境界と右の境界を維持するだけで済みます。

ACコード

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>
#include<vector>
#include<set>
#include<fstream>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(a, b) memcpy(a, b, sizeof(b))
#define INF (0x3f3f3f3f)
#define mod (ull)(1e9+7)
typedef pair<int, int> P;

namespace FastIO {
    const int bufsiz = 1 << 22;
    char buf[bufsiz];

    inline char getch() {
        static int tot;
        tot++;
        if (tot == bufsiz) {
            fread(buf, 1, bufsiz, stdin);
            tot = 0;
        }
        return buf[tot];
    }

    inline int read() {
        int x = 0;
        char c = getch();
        while (!isdigit(c))c = getch();
        while (isdigit(c))x = x * 10 + c - '0', c = getch();
        return x;
    }
}
using FastIO::read;

bool cmp(const P &x, const P &y) {
    return x.first < y.first;
}

vector<P> v(1010);

int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    int n, d;
    int cnt = 0;
    while (scanf("%d%d", &n, &d) && n != 0) {
        v.clear();
        bool ff = false;
        rep(i, 0, n - 1) {
            int x, y;
            scanf("%d%d", &x, &y);
            if (y > d) ff = true;
            v[i].first = x, v[i].second = y;
//            v.push_back(P(x, y));
        }
        if (ff) {
            printf("Case %d: -1\n", ++cnt);
            continue;
        }
        sort(v.begin(), v.begin() + n, cmp);
        int ans = 1;
        float x = -INF, y = INF;
        rep(i, 0, n - 1) {
            float lo = sqrt((float) (d * d - v[i].second * v[i].second));
            float xx = v[i].first - lo, yy = v[i].first + lo;
            if (x <= xx && yy <= y) x = xx, y = yy;
            else if (x <= xx && xx <= y && xx <= y && y <= yy) x = xx, y = y;
            else if (y == xx) x = xx, y = xx;
            else if (xx <= x && y <= yy) x = x, y = y;
            else if (y < xx) {
                ans++;
                x = xx, y = yy;
            }
        }
        printf("Case %d: %d\n", ++cnt, ans);
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/qq_45934120/article/details/107687190