zoukankan      html  css  js  c++  java
  • HDU 4400 Mines(好题!分两次计算距离)

    http://acm.hdu.edu.cn/showproblem.php?pid=4400

    题意:

    在笛卡尔坐标中有多个炸弹,每个炸弹有一个坐标值和一个爆炸范围。现在有多次操作,每次引爆一个炸弹,问每次操作会有多少个炸弹爆炸。

    思路:

    需要注意的是一个炸弹爆炸后会引起别的炸弹爆炸,然后别的炸弹爆炸后又会引起别的炸弹爆炸。

    可以考虑bfs,但是必须需要优化,首先对x坐标进行离散化,然后将该坐标的y值和id值(第几个炸弹)存入multiset中,不同的x存入不同的multiset中。当我们进行寻找时,首先可以确定x的范围,当确定了x的范围之后,对于该x值我们又可以确定y的范围,这样只需要在multiset中进行二分查找即可。不得不说这个做法实在是太妙了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<set>
     5 #include<queue>
     6 #include<cstring>
     7 using namespace std;
     8 const int maxn = 100000+5;
     9 
    10 int n, num;
    11 int x[maxn],y[maxn],d[maxn],b[maxn];
    12 bool del[maxn];
    13 
    14 struct node
    15 {
    16     int y,id;
    17     node(int y, int id):y(y),id(id){}
    18     bool operator< (const node& rhs) const
    19     {
    20         return y<rhs.y;
    21     }
    22 };
    23 
    24 multiset<node> s[maxn];
    25 multiset<node>::iterator ly, ry, it;
    26 
    27 void solve()
    28 {
    29     priority_queue<int> q;
    30     memset(del,false,sizeof(del));
    31     int m; scanf("%d",&m);
    32     while(m--)
    33     {
    34         int t; scanf("%d",&t); t--;
    35         if(del[t])  {puts("0");continue;}
    36         while(!q.empty())  q.pop();
    37         q.push(t);
    38         del[t] = true;
    39         int ans = 0;
    40         while(!q.empty())
    41         {
    42             ans++;
    43             t = q.top(); q.pop();
    44             int lx = lower_bound(b,b+num,x[t]-d[t])-b;
    45             int rx = upper_bound(b,b+num,x[t]+d[t])-b;
    46             for(int i=lx;i<rx;i++)
    47             {
    48                 int dis = d[t]-abs(x[t]-b[i]);
    49                 ly = s[i].lower_bound(node(y[t]-dis,0));
    50                 ry = s[i].upper_bound(node(y[t]+dis,0));
    51                 for(it=ly;it!=ry;it++)
    52                 {
    53                     if(!del[it->id])
    54                     {
    55                         del[it->id] = true;
    56                         q.push(it->id);
    57                     }
    58                 }
    59                 s[i].erase(ly,ry);
    60             }
    61         }
    62         printf("%d
    ",ans);
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     //freopen("in.txt","r",stdin);
    69     int kase = 0;
    70     while(~scanf("%d",&n) && n!=0)
    71     {
    72         printf("Case #%d:
    ",++kase);
    73         for(int i=0;i<n;i++)
    74         {
    75             scanf("%d%d%d",&x[i],&y[i],&d[i]);
    76             b[i] = x[i];
    77         }
    78         sort(b,b+n);
    79         num = unique(b,b+n)-b;
    80         for(int i=0;i<n;i++)  s[i].clear();
    81         for(int i=0;i<n;i++)
    82         {
    83             int tmp = lower_bound(b,b+num,x[i])-b;
    84             s[tmp].insert(node(y[i],i));
    85         }
    86         solve();
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    邮箱启用授权码发送邮件
    try里Response.end()问题
    NPOI导入excel文件为DataTable,使用SqlBulkCopy添加到数据库表
    Python入门(二)
    Python入门(一):PTVS写Python程序,调试模式下input()提示文字乱码问题
    【译】第4节---简单的Code First示例
    【译】第3节--- 配置开发环境
    【译】第2节--- 什么是Code First?
    【译】第1节--- EF Code First 介绍
    多条件查询----补发周一内容(六级让我忽略了JAVA)
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7966367.html
Copyright © 2011-2022 走看看