zoukankan      html  css  js  c++  java
  • Color the Ball(懵逼题)

    Color the Ball

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 48 Accepted Submission(s): 25
     
    Problem Description
    There are infinite balls in a line (numbered 1 2 3 ....), and initially all of them are paint black. Now Jim use a brush paint the balls, every time give two integers a b and follow by a char 'w' or 'b', 'w' denotes the ball from a to b are painted white, 'b' denotes that be painted black. You are ask to find the longest white ball sequence.
     
    Input
    First line is an integer N (<=2000), the times Jim paint, next N line contain a b c, c can be 'w' and 'b'.

    There are multiple cases, process to the end of file.
     
    Output

                Two integers the left end of the longest white ball sequence and the right end of longest white ball sequence (If more than one output the small number one). All the input are less than 2^31-1. If no such sequence exists, output "Oh, my god".
     
    Sample Input
    3
    1 4 w
    8 11 w
    3 5 b
     
    Sample Output
    8 11
     
    Author
    ZHOU, Kai
     
    Source
    ZOJ Monthly, February 2005
     
    Recommend
    Ignatius.L
     
    因为这个专题都是线段树嘛,刚开始离散化进行区间合并,但是写着写着就爆了,后来又想了一下,不用合并,只要
    set一下记录区间就行,但是边界问题各种wa,没忍住看了一发题解,看到暴力可以搞,结果就暴力一发就过了.......
    就过了......
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    char a[100002];//数组开小了,wa了几次
    int n,x,y;
    char ch;
    void init(){
        memset(a,'b',sizeof(a));
    }
    int main(){
        // freopen("in.txt","r",stdin);
        while(scanf("%d",&n)!=EOF){
            init();
            int maxnum=0,minnum=INF;//数据的范围
            for(int i=0;i<n;i++){
                cin>>x>>y>>ch;//cin处理方便的点
                if(y>maxnum)
                    maxnum=y;
    
                if(x<minnum)
                    minnum=x;
    
                for(int j=x;j<=y;j++)//模拟染色
                    a[j]=ch;
    
            }
            int sum=0;//记录连续白球的个数
            int max1=0;//记录最多连续白球个数
            int beg=minnum,end=minnum;//记录连续白球的区间
            int minpos=-1,maxpos=-1;//最大连续白球的左右区间
    
            for(int i=minnum;i<=maxnum+1;i++){
                if(a[i]=='b'){//如果当前位置是黑球的话
                    if(sum>max1){
                        max1=sum;
                        minpos=beg;
                        maxpos=end;
                    }
                    sum=0;
                    continue;
                }
                if(sum==0)
                    beg=i;
                sum++;
                end=i;
    
            }
            if(max1==0)
                cout<<"Oh, my god"<<endl;
            else
                cout<<minpos<<" "<<maxpos<<endl;
    
        }
        return 0;
    }

    经过离散化处理的线段树

    /*
    * @Author: lyucheng
    * @Date:   2017-07-03 21:05:51
    * @Last Modified by:   lyucheng
    * @Last Modified time: 2017-07-05 15:45:24
    */
    /*
    题意: 最长连续子序列的长度
    
    思路:线段树的区间set问题
    
    错误:离散化出了问题,如果单纯的去重,会产生这种错误: 
        input
        2
        1 3 w
        5 5 w
        exception output:
        1 5
        right output:
        1 3
        所以离散化的时候要改进:
            数据进行离散化的时候,开区间离散化端点,闭区间一般用两个点离散一个端点.例如:
                开区间 [1.5] 实际的离散化之后应该是 [ (1,2) , (4,5) ].
    */
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <time.h>
    #define LL long long
    #define MAXN 50000+5
    #define lson i*2,l,m
    #define rson i*2+1,m+1,r
    
    using namespace std;
    
    int n;
    LL l[MAXN],r[MAXN];
    char str[MAXN][2];
    LL X[MAXN*2];
    int len;
    int k;
    int cover[MAXN*2];
    int setd[MAXN*8];
    
    void pushup(int i,int l,int r){
        if(setd[i*2]==-1||setd[i*2+1]==-1){
            setd[i]=-1;
        }else if(setd[i*2]!=setd[i*2+1]){
            setd[i]=-1;
        }else {
            setd[i]=setd[i*2];
        }
    }
    
    void pushdown(int i,int l,int r){
        if(setd[i]!=-1){
            setd[i*2]=setd[i*2+1]=setd[i];
            setd[i]=-1;
        }
    }
    
    void build(int i,int l,int r){
        setd[i]=1;
        if(l==r) return ;
        int m=l+(r-l)/2;
        build(lson);
        build(rson);
    }
    
    void update(int ql,int qr,int val,int i,int l,int r){
        
        if(ql<=l&&r<=qr){
            setd[i]=val;
            pushdown(i,l,r);
            return ;
        }
        
        if(setd[i]==val) return ;//没有继续更新的必要
    
        if(l==r) return ;
    
        pushdown(i,r,l);
    
        int m=l+(r-l)/2;
        if(m>=ql) update(ql,qr,val,lson);
        if(m<=qr) update(ql,qr,val,rson);
        // pushup(i,l,r);
    }
    
    void query(int ql,int qr,int i,int l,int r){
        if(setd[i]!=-1){
            for(int j=l;j<=r;j++){
                cover[j]=setd[i];
            }
            return ;
        }
        int m=l+(r-l)/2;
        if(m>=ql) query(ql,qr,lson);
        if(m<=qr) query(ql,qr,rson);
    }
    
    int findx(LL key){
        int l=1,r=k,mid;
        while(l<=r){
            mid=l+(r-l)/2;
            if(X[mid]==key){
                return mid;
            }else if(X[mid]>key){
                r=mid-1;
            }else{
                l=mid+1;    
            } 
        }
        return -1;
    }
    void init(){
        len=0;
        k=1;
        memset(cover,1,sizeof cover);
    }
    
    int main(){
        // freopen("in.txt","r",stdin);
        while(scanf("%d",&n)!=EOF){
            
            init();
            for(int i=0;i<n;i++){
                scanf("%lld%lld%s",&l[i],&r[i],str[i]);
                X[++len]=l[i];
                X[++len]=r[i];
            }
    
            //处理开区间
            sort(X+1,X+len+1);
            int t=len;
            for(int i=1;i<=t;i++){
                if(X[i]-X[i-1]>1) X[++len]=X[i-1]+1;
                if(X[i]-X[i-1]>2) X[++len]=X[i]-1;
            }
    
            //去重
            sort(X+1,X+len+1);
            for(int i=2;i<=len;i++){
                if(X[i]!=X[i-1]){
                    X[++k]=X[i];
                }
            }
            // for(int i=1;i<=k;i++){
            //     cout<<X[i]<<" ";
            // }cout<<endl;
            // cout<<"k="<<k<<endl;
            build(1,1,k);
    
            for(int i=0;i<n;i++){
                int fl=findx(l[i]);
                int fr=findx(r[i]);
                if(str[i][0]=='w')
                    update(fl,fr,0,1,1,k);
                else 
                    update(fl,fr,1,1,1,k);
            }
            // cout<<"ok"<<endl;
            query(1,k,1,1,k);//更新到cover数组中
    
            // for(int i=1;i<=k;i++){
            //     cout<<cover[i]<<" ";
            // }cout<<endl;
    
            LL _max=0,_maxl,_maxr;
            int i=1;
            while(i<=k){
                if(cover[i]==0){//白色气球
                    int j=i+1;
                    while(cover[j]==0&&j<=k) j++;
                    // cout<<X[j-1]<<" "<<X[i]<<endl;
                    if(X[j-1]-X[i]+1>_max){
                        _max=X[j-1]-X[i]+1;
                        _maxl=X[i];
                        _maxr=X[j-1];
                    }
                    i = j;
                }else{
                    i++;
                }
                 // cout<<_max<<endl;
            }
            if(_max==0){
                puts("Oh, my god");
            }else{
                printf("%lld %lld
    ",_maxl,_maxr);
            }
        }
        return 0;
    }
  • 相关阅读:
    超过5名学生的课
    大的国家
    shell启动时读取的配置文件
    shell中的环境变量
    chisel中pviews命令无法使用
    shell script中的$*和$@
    OS X EI Capitan 10.11.4中sudo无法起作用的解决方法
    如何判断CPU的位数
    block中无法使用C数组变量
    布尔代数
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6543212.html
Copyright © 2011-2022 走看看