• 蓝桥杯每日一题20223.9.26


    4407. 扫雷 - AcWing题库

    题目描述

    分析

    此题目使用map等都会超时,所以我们可以巧妙的使用哈希模拟散列表,哈希表初始化为-1首先将地雷读入哈希表,找到地雷的坐标在哈希表中对应的下标,如果没有则此地雷的位置第一次出现,将其存入哈希表,di[key]表示哈希数组中key对应的地雷下标,在这些相同位置的地雷中取最大的半径,因为最大的半径炸的范围更多

    枚举导弹,如果有地雷,且没有被访问过而且其在爆炸范围之内就可以将其进行bfs

    最后遍历每个地雷看是否被标记,被标记就算答案

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. const int X = 1e9 + 1, M = 1e6 + 7, N = 5e4 + 10;
    5. struct node
    6. {
    7. int x, y, r;
    8. }b[N];
    9. ll h[M], id[M], res, n, m;
    10. bool st[N];
    11. ll get_he(int x, int y)//得到每个坐标的哈希值
    12. {
    13. return (ll)x * X + y;
    14. }
    15. int find(int x, int y)//找到坐标被哈希数组储存的下标
    16. {
    17. ll he = get_he(x, y);
    18. int key = (he % M + M) % M;//映射哈希数组内
    19. while(h[key] != -1 && h[key] != he)
    20. {
    21. key ++;
    22. if(key == M)key = 0;
    23. }
    24. return key;
    25. }
    26. bool check(int x, int y,int r, int xx, int yy)//判断是否在爆炸范围内
    27. {
    28. int d = (x - xx) * (x - xx) + (y - yy) * (y - yy);
    29. return d <= r * r;
    30. }
    31. void bfs(int pos)
    32. {
    33. queue<int>q;
    34. q.push(pos);
    35. st[pos] = true;
    36. while(!q.empty())
    37. {
    38. int t = q.front();
    39. q.pop();
    40. int x = b[t].x, y = b[t].y, r= b[t].r;
    41. for(int xx = x - r; xx <= x + r; xx ++)
    42. {
    43. for(int yy = y - r; yy <= y + r; yy ++)
    44. {
    45. int key = find(xx, yy);
    46. //是地雷,没有访问过,能炸到
    47. if(id[key] && !st[id[key]] && check(x, y, r, xx, yy))
    48. {
    49. int pos = id[key];
    50. st[pos] = true;
    51. q.push(pos);
    52. }
    53. }
    54. }
    55. }
    56. }
    57. int main()
    58. {
    59. cin >> n >> m;
    60. memset(h, -1, sizeof h);
    61. int x, y, r;
    62. for(int i = 1; i <= n; i ++)//地雷
    63. {
    64. cin >> x >> y >> r;
    65. b[i] = {x, y, r};
    66. int key = find(x, y);//找到此地雷对应的下标
    67. if(h[key] == -1)h[key] = get_he(x, y);//如果此下标没有出现过就加入
    68. if(!id[key] || b[id[key]].r < r)
    69. {
    70. id[key] = i;
    71. }
    72. }
    73. for(int i = 1; i <= m; i ++)//排雷导弹
    74. {
    75. cin >> x >> y >> r;
    76. for(int xx = x - r; xx <= x + r; xx ++)//在r的范围内,但可以以圆外的方形区域作为边界
    77. {
    78. for(int yy = y - r; yy <= y + r; yy ++)
    79. {
    80. int key = find(xx, yy);
    81. if(id[key] && !st[id[key]] && check(x, y, r, xx, yy))bfs(id[key]);
    82. }
    83. }
    84. }
    85. for(int i = 1; i <= n; i ++)
    86. {
    87. int key = find(b[i].x, b[i].y);
    88. int pos = id[key];
    89. if(pos && st[pos])res ++;
    90. }
    91. cout << res;
    92. return 0;
    93. }
  • 相关阅读:
    【​毕业季·进击的技术er​】--分享自己的经历与经验
    ✔ ★算法基础笔记(Acwing)(一)—— 基础算法(20道题)【java版本】
    数据结构刷题——栈(上)
    全套完整版实战型Java云HIS系统源码
    形态学 - 骨架
    正点原子嵌入式linux驱动开发——Linux内核定时器
    微服务学习之——nacos安装部署
    Makefile从入门到入门
    【并发编程】Lock接口
    通讯网关软件012——利用CommGate X2OPC实现MS SQL数据写入OPC Server
  • 原文地址:https://blog.csdn.net/m0_75087931/article/details/133325324