• zju1610Count the Colors


    ZOJ Problem Set - 1610
    Count the Colors

    Time Limit: 2 Seconds      Memory Limit: 65536 KB

    Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones.

    Your task is counting the segments of different colors you can see at last.


    Input

    The first line of each data set contains exactly one integer n, 1 <= n <= 8000, equal to the number of colored segments.

    Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:

    x1 x2 c

    x1 and x2 indicate the left endpoint and right endpoint of the segment, c indicates the color of the segment.

    All the numbers are in the range [0, 8000], and they are all integers.

    Input may contain several data set, process to the end of file.


    Output

    Each line of the output should contain a color index that can be seen from the top, following the count of the segments of this color, they should be printed according to the color index.

    If some color can't be seen, you shouldn't print it.

    Print a blank line after every dataset.


    Sample Input

    5
    0 4 4
    0 3 1
    3 4 2
    0 2 2
    0 2 3
    4
    0 1 1
    3 4 1
    1 3 2
    1 3 1
    6
    0 1 0
    1 2 1
    2 3 1
    1 2 0
    2 3 0
    1 2 1


    Sample Output

    1 1
    2 1
    3 1

    1 1

    0 2
    1 1


    Author: Standlove
    Source: ZOJ Monthly, May 2003

     

    乱的代码

      1 #include <bits/stdc++.h>
      2 const int MAXN=16000; 
      3 using namespace std;
      4 struct node{
      5     int l,r;
      6     int c;//color 
      7 }tree[MAXN];
      8 int n;
      9 int color[MAXN];
     10 //每个节点左右端点的颜色
     11 int leftC[MAXN];
     12 int rightC[MAXN]; 
     13 
     14 void print(){
     15     for(int i=1;i<=7;i++) cout<<tree[i].l<<" "<<tree[i].r<<" "<<tree[i].c<<endl;
     16 }
     17 
     18 void build(int p,int l,int r){
     19     tree[p].l=l;
     20     tree[p].r=r;
     21     tree[p].c=0;
     22     //拓展节点 
     23     if(l+1<r){ 
     24         int mid=(l+r)/2;
     25         build(2*p,l,mid);
     26         build(2*p+1,mid,r);
     27     }
     28 }
     29 
     30 void insert(int p,int l,int r,int c){//这里的l和r代表线段的左端点和右端点 
     31     //颜色不同才有涂色的必要 
     32     if(tree[p].c!=c){
     33         cout<<c<<endl;
     34         int mid=(tree[p].l+tree[p].r)/2;//日常拆区间 
     35         if(l==tree[p].l&&r==tree[p].r){
     36              
     37             tree[p].c=c;
     38         } 
     39         else if(tree[p].l+1==tree[p].r) return;//树的叶子节点 
     40         //区间不合适,我这是要拆区间的节奏,肯定会给加一种颜色造成混色 
     41         //可能没有交集么???不可能没有交集,不在左,毕在右,第一轮就给你分好了,所以肯定要进行母树颜色往下分的操作 
     42         else if(tree[p].c>=0) {
     43             //母树的颜色往下分 
     44             tree[2*p].c=tree[p].c;
     45             tree[2*p+1].c=tree[p].c;
     46             tree[p].c=-1;
     47             if(r<mid) insert(2*p,l,r,c);
     48             else if(l>mid) insert(2*p+1,l,r,c);
     49             else{//把线段拆了 
     50                 insert(2*p,l,mid,c);
     51                 insert(2*p+1,mid,r,c);
     52             }
     53         }
     54         
     55         
     56     } 
     57 }
     58 
     59 void count1(int p,int lc,int rc){
     60     cout<<"p:"<<p<<" lc:"<<lc<<" rc"<<rc<<endl;
     61     int tl=0,tr=0;
     62     //单一颜色才计数 
     63     if(tree[p].c>=0){
     64         cout<<"1"<<endl;
     65         cout<<"tree[p].c:"<<tree[p].c<<endl;
     66         lc=tree[p].c;
     67         rc=tree[p].c; 
     68         color[tree[p].c]++;//这种颜色的线段数加1 
     69         cout<<"p:"<<p<<" lc:"<<lc<<" rc"<<rc<<endl;
     70     } 
     71     else if(tree[p].r-tree[p].l>1){
     72         count1(2*p,lc,tl);
     73         count1(2*p+1,tr,rc);
     74     }
     75     //每一轮做完就看p的左右孩子是否同色或者部分同色 
     76     if(tree[2*p].r==tree[2*p+1].l){
     77         color[tree[p].c]--;
     78     }
     79 } 
     80 
     81 void count2(int p){
     82     //单一颜色才计数 
     83     if(tree[p].c>=0){
     84         leftC[p]=tree[p].c;
     85         rightC[p]=tree[p].c; 
     86         color[tree[p].c]++;//这种颜色的线段数加1 
     87         return;
     88     } 
     89     else if(tree[p].r-tree[p].l>1){
     90         count2(2*p);
     91         leftC[p]=leftC[2*p];
     92         count2(2*p+1);
     93         rightC[p]=rightC[2*p+1];
     94     }
     95     //每一轮做完就看p的左右孩子是否同色或者部分同色 
     96     if(rightC[2*p]==leftC[2*p+1]){
     97         color[rightC[2*p]]--;
     98     }
     99 } 
    100 
    101 
    102 void printColor(){
    103     for(int i=1;i<=5;i++) cout<<color[i]<<" "; cout<<endl;
    104 } 
    105 
    106 int main(){
    107     build(1,1,5);
    108     insert(1,1,4,4);
    109     insert(1,4,5,5);
    110     count2(1);
    111     print(); 
    112     printColor();
    113     return 0;
    114 } 

    题解/solution:

      这题大体和我写的解题报告(PPT1 例2)相同,只是在统计算法上要改一下。Look down!

      图,come out.            (懒得画树,将就一下)

      用ls表示上一个颜色,如果当前颜色与ls不同,那给这个颜色加一。例:

      ls颜色为空,而一区间为红,红加一,ls=红。
      ls颜色为红,而三区间为蓝,蓝加一,ls=蓝。

      以此类推......

      1 type  
      2   arr=record  
      3     l,r:longint;  
      4     color:longint;  
      5   end;  
      6 var  
      7   tree:array [0..32001] of arr;  
      8   ans:array [0..8001] of longint;  
      9   n,m,ls,max_co:longint;  
     10 procedure cre(p,b,e:longint);  
     11 var  
     12   m:longint;  
     13 begin  
     14   with tree[p] do  
     15     begin  
     16       l:=b; r:=e; color:=-1;  
     17       if e-b=1 then exit;  
     18       m:=(b+e) div 2;  
     19       cre(p*2,b,m);  
     20       cre(p*2+1,m,e);  
     21     end;  
     22 end;  
     23   
     24 procedure ins(p,a,b,c:longint);  
     25 var  
     26   m:longint;  
     27 begin  
     28   with tree[p] do  
     29     begin  
     30       if color<>c then  
     31         begin  
     32           m:=(l+r) div 2;  
     33           if (a=l) and (b=r) then color:=c else  
     34             begin  
     35               if color>=0 then  
     36                 begin  
     37                   tree[p*2].color:=color;  
     38                   tree[p*2+1].color:=color;  
     39                 end;  
     40           color:=-2;  
     41           if b<=m then ins(p*2,a,b,c) else  
     42             if a>=m then ins(p*2+1,a,b,c) else  
     43               begin  
     44                 ins(p*2,a,m,c);  
     45                 ins(p*2+1,m,b,c);  
     46               end;  
     47             end;  
     48         end;  
     49     end;  
     50 end;  
     51   
     52 procedure count(p:longint);  
     53 begin  
     54   with tree[p] do  
     55     begin  
     56       if color>=0 then  
     57         begin  
     58           if color<>ls then  
     59             begin  
     60               inc(ans[color]);  
     61               ls:=color;  
     62             end;  
     63           exit;  
     64         end;  
     65       if color=-1 then  
     66         begin  
     67           ls:=color;  
     68           exit;  
     69         end;  
     70       count(p*2);  
     71       count(p*2+1);  
     72     end;  
     73 end;  
     74   
     75 procedure main;  
     76 var  
     77   i,x,y,z:longint;  
     78 begin  
     79   m:=8000;  
     80   while not eof do  
     81     begin  
     82       fillchar(ans,sizeof(ans),0);  
     83       readln(n);  
     84       ls:=-1; max_co:=-(maxlongint div 3);  
     85       cre(1,0,m);  
     86       for i:=1 to n do  
     87         begin  
     88           readln(x,y,z);  
     89           ins(1,x,y,z);  
     90           if z>max_co then max_co:=z;  
     91         end;  
     92       count(1);  
     93       for i:=0 to max_co do  
     94         if ans[i]>0 then  
     95           writeln(i,' ',ans[i]);  
     96       writeln;  
     97     end;  
     98 end;  
     99   
    100 begin  
    101   main;  
    102 end.  
  • 相关阅读:
    关于数据集的划分--训练集、验证集和测试集
    关于过拟合的问题总结
    paddle 09-13
    关于NLP多分类任务评价指标的总结
    数组题解
    多进程-协程
    多任务-进程
    多任务-线程
    网络-tcp
    网络-udp
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7566457.html
Copyright © 2020-2023  润新知