zoukankan      html  css  js  c++  java
  • TJU 4072 3D Birds-Shooting Game

    4072.   3D Birds-Shooting Game
    Time Limit: 3.0 Seconds   Memory Limit: 65536K Total Runs: 167   Accepted Runs: 37

    There are N birds in a 3D space, let x, y and z denote their coordinates in each dimension. You, the excellent shooter, this time sit in a helicopter and want to shoot these birds with your gun. Through the window of the helicopter you can only see a rectangle area and you choose to shoot the highest bird in view (the helicopter is above all the birds and the rectangle area is parallel to the ground). Now given the rectangle area of your view, can you figure out which bird to shoot?

    Input

    First line will be a positive integer T (1≤T≤10) indicating the test case number.. Following there are T test cases.. Each test case begins with a positive integer N (1≤N≤10000), the number of birds.. Then following N lines with three positive integers x, y and z (1≤x,y,z≤100000), which are the coordinates of each bird (you can assume no two birds have the same height z).. Next will be a positive integer Q (1≤Q≤10000) representing the number of query.. Following Q lines with four positive integers which are the lower-left and upper-right points' coordinates of the rectangle view area.. (please note that after each query you will shoot down the bird you choose and you can't shoot it any more in the later).

    Output

    For each query output the coordinate of the bird you choose to shoot or output 'Where are the birds?' (without the quotes) if there are no birds in your view.

    Sample Input

    2
    3
    1 1 1
    2 2 2
    3 3 3
    2
    1 1 2 2
    1 1 3 3
    2
    1 1 1
    3 3 3
    2
    2 2 3 3
    2 2 3 3
    
    

    Sample Output

    2 2 2
    3 3 3
    3 3 3
    Where are the birds?
    
    


    Source: TJU Team Selection 2014 Round1

    题意:三维空间中有N个点,给出其坐标;接下来Q个询问,每次询问给出一个垂直于z轴的矩形,矩形边界与坐标轴平行,求出此矩形范围内z坐标最大的点,输出其坐标,如果没有满足条件的点,输出"Where are the birds?"。每个点只能被输出一次。(所有点的z坐标值都不相同)

    分析:典型的k-d树,在三维空间中查询满足条件的解。建树的时候,依次按照x,y,z来划分空间(也可以优化)。查询的时候,如果遇到以z坐标划分空间的情况,则先查询上部空间,查询下层空间的时候,先比较当前找到的答案与划分点的z坐标值,如果当前答案比该值还大,则没有再必要查询下层空间。

    代码如下:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 #define N 10005
      6 
      7 int idx;
      8 struct point{
      9     int x[3];
     10     bool operator < (const point &a) const{
     11         return x[idx] < a.x[idx];
     12     }
     13 };
     14 
     15 point p[N];
     16 point tr[N<<2];
     17 int cnt[N<<2];
     18 bool flag[N<<2];
     19 
     20 int x1, x2, y1, y2;
     21 void build(int l, int r, int u, int dep)
     22 {
     23     if(l > r) return;
     24     cnt[u] = r-l+1;
     25     if(l == r)
     26     {
     27         tr[u] = p[l];
     28         return;
     29     }
     30     idx = dep%3;
     31     int mid = l+r>>1;
     32     nth_element(p+l, p+mid, p+r+1);
     33     tr[u] = p[mid];
     34     build(l, mid-1, u<<1, dep+1);
     35     build(mid+1, r, u<<1|1, dep+1);
     36 }
     37 
     38 int ans, id;
     39 bool check(point u)
     40 {
     41     return u.x[0] >= x1 && u.x[0] <= x2 && u.x[1] >= y1 && u.x[1] <= y2;
     42 }
     43 void query(int u, int dep)
     44 {
     45     if(cnt[u] == 0) return;
     46     if(!flag[u] && check(tr[u]))
     47         if(tr[u].x[2] > ans) ans = tr[u].x[2], id = u;
     48     int tid = dep%3;
     49     if(tid == 0)
     50     {
     51         if(x2 < tr[u].x[0]) query(u<<1, dep+1);
     52         else if(x1 > tr[u].x[0]) query(u<<1|1, dep+1);
     53         else {
     54             query(u<<1, dep+1);
     55             query(u<<1|1, dep+1);
     56         }
     57     }
     58     else if(tid == 1)
     59     {
     60         if(y2 < tr[u].x[1]) query(u<<1, dep+1);
     61         else if(y1 > tr[u].x[1]) query(u<<1|1, dep+1);
     62         else {
     63             query(u<<1, dep+1);
     64             query(u<<1|1, dep+1);
     65         }
     66     }
     67     else if(tid == 2)
     68     {
     69         query(u<<1|1, dep+1);
     70         if(ans < tr[u].x[2])//这儿因为写成if(ans == -1)错了很多次
     71             query(u<<1, dep+1);
     72     }
     73 }
     74 
     75 int main()
     76 {
     77     int T, n, q;
     78     scanf("%d", &T);
     79     while(T--)
     80     {
     81         scanf("%d", &n);
     82         for(int i = 0; i < n; i++) scanf("%d %d %d", &p[i].x[0], &p[i].x[1], &p[i].x[2]);
     83         memset(flag, 0, sizeof(flag));
     84         memset(cnt, 0, sizeof(cnt));
     85         build(0, n-1, 1, 0);
     86 
     87         scanf("%d", &q);
     88         while(q--)
     89         {
     90             ans = -1;
     91             scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
     92             query(1, 0);
     93             if(ans == -1)
     94                 puts("Where are the birds?");
     95             else{
     96                 printf("%d %d %d
    ", tr[id].x[0], tr[id].x[1], tr[id].x[2]);
     97                 flag[id] = 1;
     98             }
     99         }
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    使用shell从DB2数据库导出数据
    kettle插入/更新
    kettle删除资源库中的转换或者作业
    DB2中的转义字符
    Kettle行列转换
    Linux查看文件以及文件夹的大小
    Linux下如何查看JDK安装路径
    使用Linux调用资源库中的Job报错-ERROR: No repository provided, can't load job.
    通过shell脚本获取日期,并赋给变量
    批处理判断是否存在文件,存在则运行另外一个bat文件
  • 原文地址:https://www.cnblogs.com/beisong/p/4425490.html
Copyright © 2011-2022 走看看