hdu-5199(离线化)

Gunner

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 769    Accepted Submission(s): 347


Problem Description
Long long ago, there is a gunner whose name is Jack. He likes to go hunting very much. One day he go to the grove. There are  n  birds and  n  trees. The  ith  bird stands on the top of the  ith  tree. The trees stand in straight line from left to the right. Every tree has its height. Jack stands on the left side of the left most tree. When Jack shots a bullet in height H to the right, the bird which stands in the tree with height  H  will falls.
Jack will shot many times, he wants to know how many birds fall during each shot.

a bullet can hit many birds, as long as they stand on the top of the tree with height of  H .
 

Input
There are multiple test cases (about 5), every case gives  n,m  in the first line,  n  indicates there are  n  trees and  n  birds,  m  means Jack will shot  m  times.

In the second line, there are  n  numbers  h[1],h[2],h[3],,h[n]  which describes the height of the trees.

In the third line, there are m numbers  q[1],q[2],q[3],,q[m]  which describes the height of the Jack’s shots.

Please process to the end of file.

[Technical Specification]

1n,m1000000(106)

1h[i],q[i]1000000000(109)

All inputs are integers.
 

Output
For each  q[i] , output an integer in a single line indicates the number of birds Jack shot down.
 

Sample Input
  
  
4 3 1 2 3 4 1 1 4
 

Sample Output
  
  
1 0 1
题意:

Gunner

 
 Time Limit: 8000/4000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
很久很久以前,有一个叫Jack的枪手。他非常喜欢打猎。一天,他去了一个小树林。那儿有
      
      
       
       n
      
      只鸟,还有
      
      
       
       n
      
      棵树。第
      
      
       
       i
      
      只鸟站在第
      
      
       
       i
      
      棵树的顶端。这些树从左到右排成一条直线。每一棵树都有它的高度。Jack站在最左边那棵树的左边。当Jack在高度为
      
      
       
       H
      
      的地方向右发射一棵子弹时,站在高度为
      
      
       
       H
      
      的树上的鸟儿就会落下来。
Jack会射击多次,他想知道每次射击会有多少鸟儿落下来。
输入描述
多组测试数据(大概
      
      
       
       5
      
      组),每一组的第一行给出
      
      
       
       n,m
      
      
      
      
       
       n
      
      表示有
      
      
       
       n
      
      棵树和
      
      
       
       n
      
      只鸟,
      
      
       
       m
      
      表示Jack会射击
      
      
       
       m
      
      次。
在第二行,有
      
      
       
       n
      
      个整数, 
      
      
       
       h[1],h[2],h[3],,h[n]
      
      表示这些树的高度。
在第三行,有
      
      
       
       m
      
      个整数, 
      
      
       
       q[1],q[2],q[3],,q[m]
      
      表示Jack射击的高度。

[参数约定]

      
      
       
       1n,m1000000(106)
      
      

      
      
       
       1h[i],q[i]1000000000(109)
      
      
输出描述
对于每一个
      
      
       
       q[i]
      
      ,在一行中输出Jack射落了几只鸟。
输入样例
4 3
1 2 3 4
1 1 4
输出样例
1
0
1
Hint
大数据输入,推荐使用快速读读入。


思路: 显然这道题数据太大,直接开1e9的数组是不可能的
但是可以用离线化 ,将数据缩小,因为输入的数据是不可能超过2*1e6的
那么就将1,1000,1000000转化为1,2,3
基本方法就是排序、去重、用二分在数组中找出对应位置
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <map>
#define maxn 205
using namespace std;
const int inf=0x3f3f3f3f;
map<int,int>mapp;
int num[2000005];
int h[1000005];
int q[1000005];
int vis[1000005];
int er(int len, int goal)
{
    int low = 0;
    int high = len - 1;
    while(low <= high)
    {
        int middle = (low + high)/2;
        if(num[middle] == goal)
            return middle;
        else if(num[middle] > goal)
            high = middle - 1;
        else
            low = middle + 1;
    }
    return -1;
}
int main()
{
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(int i=0;i<n;i++)
            scanf("%d",h+i),num[i]=h[i];
        for(int i=n;i<n+m;i++)
            scanf("%d",q+i-n),num[i]=q[i-n];
        sort(num,num+n+m);
        int len=unique(num,num+n+m)-num;
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
        {
            int x=er(len,h[i]);
            vis[x]++;
        }
        for(int i=0;i<m;i++)
        {
            int x=er(len,q[i]);
            printf("%d\n",vis[x]);
            vis[x]=0;
        }
    }
    return 0;
}


但是因为我没有用快速读入,所以C++可以过,G++会TLE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值