AcWing 4407.扫雷

思路:DFS+二分

通过对于题目的理解,我们知道,这个题是典型的DFS,因为这里的地雷都是连锁反应进行爆炸的,所以我们可以用DFS来遍历。

思路就是对于每一个火箭进行遍历坐标,遍历到一个火箭的坐标之后看看它的范围内有没有地雷,有的话就是地雷炸了,然后换做以这个炸了的地雷为起点,看看其他地雷炸了没有。暴力DFS是这个样子:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath> 
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include <iomanip>
#include<sstream>
#include<numeric>
#include<map>
#include<limits.h>
#include<unordered_set>
#include<set>
#define int long long
#define MAX 5010
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef pair<int, int> PII;
int n, m;
int counts;
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };
queue<PII>q;
struct Node {
    int x;
    int y;
    int r;
}lei[MAX],rocket[MAX];
bool flag[MAX];
bool cmp(Node a, Node b) {
    return a.x < b.x;
}
double dis(Node a, Node b) {
    return sqrt(abs((a.x - b.x)) * abs((a.x - b.x)) + abs(a.y - b.y) * abs(a.y - b.y));
}
void dfs(Node u) {
    _for(i, 1, n + 1) {
        if (!flag[i] && dis(u, lei[i]) <= u.r) {
            flag[i] = 1;
            counts++;
            dfs(lei[i]);
        }
    }
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m;
    _for(i, 1, n + 1)
    {
        cin >> lei[i].x >> lei[i].y >> lei[i].r;
    }
    _for(i, 1, m + 1)
        cin >> rocket[i].x >> rocket[i].y >> rocket[i].r;
    _for(i, 1, m + 1) {
        dfs(rocket[i]);
    }
    cout << counts;
    return 0;
}

OK,这样的话是会超时的,因为这个DFS做法的范围顶多就到1000数据这里,而题目中的要求是到5e4的数据。所以我们需要进行优化。

由于我们遍历的时候似乎把范围扩大的有点多了,比如,如果说一个地雷不在火箭的范围内,我们还是进行了判断和遍历,这个时候其实就已经耗费了很长时间。所以,其实优化也就是对于DFS的范围进行了缩减,也就是你们常说的剪枝。我们怎么剪枝?

我们发现,在这个(x-r,x+r)的范围内是可以引爆地雷的,也就是说,我们提前给出了范围,事先排除掉其他不符合范围i的地雷,也就是做了一个预处理,然后我们再去判断在这个范围内的地雷怎么连锁爆炸,然后统计个数。

这时你应该会想到一个技巧,就是二分,我们肯定应该从近距离到远距离进行判断呀,这样才能保证我们每一次的选择都是最佳的,也是更保险的做法。

在AcWing上,这里的会卡到最后一个50000的数据,这样的话大家就去看哈希的做法吧,这里就不详细讲述了。

上代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath> 
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include <iomanip>
#include<sstream>
#include<numeric>
#include<map>
#include<limits.h>
#include<unordered_set>
#include<set>
#define int long long
#define MAX 50010
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef pair<int, int> PII;
int n, m;
int counts;
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };
queue<PII>q;
struct Node {
    int x;
    int y;
    int r;
}lei[MAX],rocket[MAX];
bool flag[MAX];
bool cmp(Node a, Node b) {
    return a.x < b.x;
}
double dis(Node a, Node b) {
    return sqrt(abs((a.x - b.x)) * abs((a.x - b.x)) + abs(a.y - b.y) * abs(a.y - b.y));
}
void dfs(Node u) {
    int l = 0;
    int r = n - 1;
    int lmid = 0;
    int rmid = 0;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (lei[mid].x < u.x - u.r)
            l = mid + 1;
        else if (lei[mid].x == u.x - u.r)
            break;
        else
            r = mid - 1;
    }
    lmid = l;
    l = 0;
    r = n - 1;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (lei[mid].x > u.x + u.r)
            r = mid - 1;
        else if (lei[mid].x == u.x + u.r)
            break;
        else
            l = mid + 1;
    }
    rmid = r;
    _for(i, lmid, rmid + 1) {
        if (!flag[i] && dis(u, lei[i]) <= u.r) {
            flag[i] = 1;
            counts++;
            dfs(lei[i]);
        }
    }
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m;
    _for(i, 0, n)
    {
        cin >> lei[i].x >> lei[i].y >> lei[i].r;
    }
    _for(i, 0, m)
        cin >> rocket[i].x >> rocket[i].y >> rocket[i].r;
    sort(lei, lei + n, cmp);
    _for(i, 0, m) {
        dfs(rocket[i]);
    }
    cout << counts;
    return 0;
}

相关推荐

  1. AcWing 4407.扫雷

    2024-04-05 16:42:04       37 阅读
  2. AcWing 4405. 统计子矩阵(双指针,前缀和)

    2024-04-05 16:42:04       37 阅读
  3. [c]<span style='color:red;'>扫雷</span>

    [c]扫雷

    2024-04-05 16:42:04      68 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-05 16:42:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-05 16:42:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-05 16:42:04       82 阅读
  4. Python语言-面向对象

    2024-04-05 16:42:04       91 阅读

热门阅读

  1. 基于SpringBoot + Vue 的电影售票及影院管理系统

    2024-04-05 16:42:04       35 阅读
  2. 【C脚本】计算PCM的DBFS(分贝全尺度)

    2024-04-05 16:42:04       38 阅读
  3. 领地选择

    2024-04-05 16:42:04       39 阅读
  4. test000000

    2024-04-05 16:42:04       38 阅读
  5. LLM记录1

    2024-04-05 16:42:04       38 阅读
  6. 【C++算法】 卡常技巧

    2024-04-05 16:42:04       48 阅读
  7. Python程序设计 垃圾回收机制&鸭子类型

    2024-04-05 16:42:04       31 阅读