hdu 5200 Trees

来源:互联网 发布:工资软件下载 编辑:程序博客网 时间:2024/04/23 17:10

Trees

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 989    Accepted Submission(s): 306


Problem Description
Today CodeFamer is going to cut trees.There are N trees standing in a line. They are numbered from 1 to N. The tree numbered i has height hi. We say that two uncutted trees whose numbers are x and y are in the same block if and only if they are fitting in one of blow rules:

1)x+1=y or y+1=x;

2)there exists an uncutted tree which is numbered z, and x is in the same block with z, while y is also in the same block with z.

Now CodeFamer want to cut some trees whose height is not larger than some value, after those trees are cut, how many tree blocks are there?
 

Input
Multi test cases (about 15).

For each case, first line contains two integers N and Q separated by exactly one space, N indicates there are N trees, Q indicates there are Q queries.

In the following N lines, there will appear h[1],h[2],h[3],,h[N] which indicates the height of the trees.

In the following Q lines, there will appear q[1],q[2],q[3],,q[Q] which indicates CodeFamer’s queries.

Please process to the end of file.

[Technical Specification]

1N,Q50000

0h[i]1000000000(109)

0q[i]1000000000(109)
 

Output
For each q[i], output the number of tree block after CodeFamer cut the trees whose height are not larger thanq[i].
 

Sample Input
3 252362
 

Sample Output
02
Hint
In this test case, there are 3 trees whose heights are 5 2 3.For the query 6, if CodeFamer cuts the tree whose height is not large than 6, the height form of left trees are -1 -1 -1(-1 means this tree was cut). Thus there is 0 block.For the query 2, if CodeFamer cuts the tree whose height is not large than 2, the height form of left trees are 5 -1 3(-1 means this tree was cut). Thus there are 2 blocks.
 

Source
BestCoder Round #36 ($)
题意:
给出一列树,有n棵,给出m个查询,每个查询要找到比查询给出的值小的树被砍掉后剩下的连续区间的个数
题目分析:
很简单的离线处理,bestcoder少见的水题,首先对树按照树的高度从小到大排序,然后对查询从小到大排序,然后遍历所有的树,删掉这棵树后,判断左右相邻是否有树,如果只有一边有树,那么当前连续区间的个数不变,如果两边都没有树,那么当前连续的区间个数减一,如果两边都有树,那么当前连续的区间的个数加一,然后判断当前树是不是这个高度树的最后一棵,如果是,那么继续判断当前的查询是不是已经把比它小的树全部砍断,如果是的话,那么记录答案,如果不是,那么继续处理,等待条件允许的情况

ac代码如下,好久不敲题,水题都没有1A,罪过啊~
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#define MAX 50007using namespace std;struct Node{    int x,h;    bool operator < ( const Node& a ) const    {        return h < a.h;    }}p[MAX];struct Query{    int v,id,ans;}q[MAX];bool cmp1 ( Query a , Query b ){    return a.v < b.v;}bool cmp2 ( Query a , Query b ){    return a.id < b.id;}int loc[MAX];int n,m;int main ( ){    while ( ~scanf ( "%d%d" , &n , &m ) )    {        memset ( loc , 0 , sizeof ( loc ) );        for ( int i = 0 ; i < n ; i++ )        {            scanf ( "%d" , &p[i].h );            p[i].x = i;        }        for ( int i = 0 ; i < m ; i++ )        {            scanf ( "%d" , &q[i].v );            q[i].id = i;        }        sort ( p , p + n );        sort ( q , q + m , cmp1 );        int i = 0 , j = 0;        int num = 1;        while ( j < m && q[j].v < p[i].h )            q[j++].ans = 1;         while ( j != m && i != n )        {            int x = p[i].x;            int temp = -1;            if ( x > 0 && !loc[x-1] )                temp++;            if ( x < n-1 && !loc[x+1] )                temp++;            num += temp;            loc[x] = 1;            if ( i == n-1 )            {                while ( j < m && q[j].v >= p[i].h )                    q[j++].ans = num;             }            else if ( p[i].h != p[i+1].h )            {                while ( j < m && q[j].v >= p[i].h && q[j].v < p[i+1].h )                    q[j++].ans = num;            }            if ( j == m ) break;             i++;        }        while ( j != m )        {            q[j++].ans = num;        }        sort ( q , q+m , cmp2 );        for ( int i = 0 ; i < m ; i++ )            printf ( "%d\n" , q[i].ans );    }        }


0 0
原创粉丝点击