zoukankan      html  css  js  c++  java
  • The Ninth Hunan Collegiate Programming Contest (2013) Problem H

    Problem H

    High bridge, low bridge

    Q: There are one high bridge and one low bridge across the river. The river has flooded twice, why the high bridge is flooded twice but the low bridge is flooded only once?

    A: Because the lower bridge is so low that it's still under water after the first flood is over.

    If you're confused, here's how it happens:

    • Suppose high bridge and low bridge's heights are 2 and 5, respectively, and river's initial water level is 1.
    • First flood: the water level is raised to 6(Both bridges are flooded), and then back to 2(high bridge is not flooded anymore, but low bridge is still flooded).
    • Second flood: the water level is raised to 8(The high bridge is flooded again), and then back to 3.

    Just a word game, right? The key is that if a bridge is still under water (i.e. the water level is no less than the bridge height) after a flood, then next time it will not be considered flooded again.

    Suppose the i-th flood raises the water level to ai and then back to bi. Given n bridges' heights, how many bridges are flooded at least k times? The initial water level is 1.

    Input

    The input contains at most 25 test cases. Each test case begins with 3 integers n, m, k in the first line (1<=n,m,k<=105). The next line contains n integers hi, the heights of each bridge (2<=hi<=108). Each of the next m lines contains two integers ai and bi (1<=bi<ai<=108, ai>bi-1). The file size of the whole input does not exceed 5MB.

    Output

    For each test case, print the number of bridges that is flooded at least k times.

    Sample Input

    2 2 2
    2 5
    6 2
    8 3
    5 3 2
    2 3 4 5 6
    5 3
    4 2
    5 2
    

    Output for the Sample Input

    Case 1: 1
    Case 2: 3
    

    Explanation

    For the second sample, 5 bridges are flooded 1, 2, 3, 2, 0 times, respectively.


    The Ninth Hunan Collegiate Programming Contest (2013)

    Problemsetter: Rujia Liu Special Thanks: Feng Chen, Md. Mahbubul Hasan

        这道试题很好。用笔画一下,其实就是区间更新,区间询问的树状数组吧,关键是求更新的区间,其实直接使用StL的查找也是可以的。还是那个道理,二分查找的变法很多,

    不要太依赖STL ,基础一定要打好。

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    #include <queue>
    #include <set>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <math.h>
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std ;
    typedef long long LL ;
    const int Max_N=100008 ;
    struct Node{
         int raise ;
         int down ;
    };
    Node water[Max_N] ;
    int bridge[Max_N] ;
    int N ,M ,K ;
    int find_first_big_id(int x){
       int Left=1 ;
       int Right=N ;
       int mid ;
       int ans_id=-1 ;
       while(Left<=Right){
            mid=(Left+Right)>>1  ;
            if(bridge[mid]>x){
                ans_id=mid ;
                Right=mid-1 ;
            }
            else
                Left=mid+1 ;
       }
       return ans_id ;
    }
    int find_last_less_or_equal_id(int x){
        int Left=1 ;
        int Right=N ;
        int mid ;
        int ans_id=-1 ;
        while(Left<=Right){
            mid=(Left+Right)>>1  ;
            if(bridge[mid]>x){
                Right=mid-1 ;
            }
            else{
                ans_id=mid ;
                Left=mid+1 ;
            }
        }
        return ans_id ;
    }
    int C[Max_N] ;
    inline int lowbit(int x){
       return x&(-x) ;
    }
    void Insert(int id ,int x){
       while(id<=N){
            C[id]+=x ;
            id+=lowbit(id) ;
       }
    }
    int get_sum(int id){
       int sum=0 ;
       while(id>=1){
           sum+=C[id] ;
           id-=lowbit(id) ;
       }
       return sum ;
    }
    int main(){
       /*int x ;
       while(cin>>N>>x){
           for(int i=1;i<=N;i++)
               cin>>bridge[i] ;
           cout<<find_last_less_or_equal_id(x)<<endl ;
       }*/
       int L ,R ,ans ,k=1 ;
       while(scanf("%d%d%d",&N,&M,&K)!=EOF){
            for(int i=1;i<=N;i++)
                scanf("%d",&bridge[i]) ;
            for(int i=1;i<=M;i++)
                scanf("%d%d",&water[i].raise,&water[i].down) ;
            sort(bridge+1,bridge+1+N) ;
            water[0].down=0 ;
            fill(C,C+N+1,0) ;
            for(int i=0;i<M;i++){
                L=find_first_big_id(water[i].down) ;
                R=find_last_less_or_equal_id(water[i+1].raise) ;
               // cout<<L<<"  "<<R<<endl  ;
                if(L==-1||R==-1)
                    continue ;
    
                Insert(L,1) ;
                Insert(R+1,-1) ;
            }
            ans=0 ;
            for(int i=1;i<=N;i++){
                if(get_sum(i)>=K)
                    ans++ ;
            }
            printf("Case %d: %d
    ",k++,ans) ;
       }
       return 0 ;
    }
  • 相关阅读:
    2019-2020信息安全系统设计基础 20175306 20175309 20175326 实验二 固件程序设计
    2019-2020信息安全系统设计基础 20175306 20175309 20175326 实验一 开发环境的熟悉
    2018-2019-2 20175306实验五《网络编程与安全》实验报告
    2018-2019-2 20175306实验四《Android程序设计》实验报告
    20175306王佳烁第十一周学习总结
    20175306王佳烁第十周学习总结
    20165229 NetSec Exp9 Web安全基础
    2018-2019-2 20165229《网络对抗技术》Exp 8 Web基础
    20165229《网络对抗技术》Exp7 网络欺诈防范
    20165229《网络攻防技术》Exp6 信息搜集与漏洞扫描
  • 原文地址:https://www.cnblogs.com/liyangtianmen/p/3371301.html
Copyright © 2011-2022 走看看