Count the Colors

来源:互联网 发布:初中网络课程哪家好 编辑:程序博客网 时间:2024/06/05 08:05
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



这道题我搞了好久啊,知识都在代码里。

#include<iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>using namespace std;const int maxes = 20001;int n,temp=-1;int color[8001];struct node{int l;int r;int color;}t[maxes];void build(int a,int b,int i){t[i].l=a;t[i].r=b;t[i].color=-1; //-1代表没有颜色 if(a+1 == b) return ;  //这里的a+1==b 这个判断条件很值得思考,我们染的是区间,那么最小的单位就是1,这个区间最值//区间求和什么的有差别。 int mid=(a+b)/2;build(a,mid,i*2);build(mid,b,i*2+1);  //这里是超级重点,我原先是mid加一,但我TM的又忘了这是区间染色,不是点染色 }void query(int a,int b,int c,int i){if(a==b) return ;if(t[i].color==c) return ;   //如果T[I]所包含的区间已经是所要染的颜色,那么就没有再染下去的必要了。 if(a<=t[i].l && b>=t[i].r)  //如果染色区间包含t[i]所代表的区间,那么对其染色,并且直接return 就行。{t[i].color=c;    //其实在这里,我们应该顺着把他的左右儿子也全都染上色的/*int pos=i;int qos=i;while(t[pos*2].l!=t[pos*2].r){t[pos*2].color=i;pos=pos*2;t[qos*2+1].color=i;qos=(qos*2+1); }*/return ;}if(t[i].color>-1)  /*能够进入if语句代表当前t[i]代表的区间内已经染过色,而今又有其他颜色来染色,就需要特判了。这里有一个点你也许会有疑问,就是现在要染的区间覆盖掉之前的颜色的区间呢?也就是说虽说在t[i]所包含的区间里已经染色了,但如果我现在a-b区间覆盖了t[i]的区间呢,这你大可不必担心,因为能够执行到这,说明上面那个if语句不成立,上面那个if语句不成立代表三种情况,这两个区间相交和包含(却和上面你所担心的包含正好反着) ,因此,我们可以确定,在t[i]所在的区间里必定至少有两种颜色。*/ {t[i*2].color=t[i].color; /*说真的,我觉得这里才是最难的地方,更新啊,我本来还一直纳闷既然父节点的颜色染好了左右儿子还需要再更新呢!!!???我仔细瞧,仔细看终于发现了问题,我们这个query函数唯一对区间有染色行为的就是第三个if语句,在这条语句里面有一个最重要的语句:return 你想想,这个return导致的后果就是i的左右儿子并没有被染色,说到这一切就明了了。*/ t[i*2+1].color=t[i].color;t[i].color=-2;}int mid=(t[i].l+t[i].r)/2;if(a>=mid) query(a,b,c,i*2+1);else if(b<=mid) query(a,b,c,i*2);else{query(a,mid,c,i*2);query(mid,b,c,i*2+1);}}void count(int n){if(t[n].color!=-2 && t[n].color!=-1) //说明在这个区间里只有一种染色 {if(t[n].color!=temp){color[t[n].color]++;temp=t[n].color;}return ;}if(t[n].l+1 != t[n].r){count(n*2);count(n*2+1);}else temp=-1;}int main(){int start,end,col,MAX=-1,i;while(~scanf("%d",&n)){MAX=-1;temp=-1;memset(color,0,sizeof(color));build(0,8000,1);//printf("wenti\n");for(i=1;i<=n;i++){cin>>start>>end>>col;if(col>MAX) MAX=col;query(start,end,col,1);}count(1);//printf("dslkfj\n");for(i=0;i<=MAX;i++){//printf("jinl\n");if(color[i]!=0){printf("%d %d\n",i,color[i]);}}printf("\n");}return 0; } 


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 潞城镇剩下5个村怎么办 高三复读生学籍怎么办 被检精子总数少怎么办 前向运动精子17%怎么办 精子形态正常率1怎么办 精子形态正常率2怎么办 精子头部畸形率高怎么办 椎底动脉供血不足怎么办 颈椎动脉供血不足怎么办 颈椎病引起头晕脑供血不足怎么办 淘宝店被释放了怎么办 被枣蝎子蛰了怎么办 六角螺丝拧花了怎么办 苹果螺丝滑丝了怎么办 六角螺帽拧花了怎么办 六角螺母拧花了怎么办 内六角螺丝滑丝怎么办 十字螺丝拧花了怎么办 梅花螺丝滑丝了怎么办 螺丝孔道滑丝了,怎么办 锅把铆钉松啦怎么办 膨胀螺丝孔大了怎么办 戒指不圆了怎么办妙招 眼镜框的腿断了怎么办 弹簧腿眼镜坏了怎么办 vps搭建ss被墙怎么办 注塑机螺杆黏料怎么办 分解师耐久度0了怎么办 有鼻涕擤不出来怎么办 擤鼻涕耳朵堵了怎么办 脸用什么都过敏怎么办 1岁宝宝流清鼻涕怎么办 2岁宝宝流清鼻涕怎么办 3岁儿童流清鼻涕怎么办 鼻子老是流清水鼻涕怎么办 5岁儿童感冒鼻塞怎么办 3岁宝宝感冒鼻塞怎么办 宝宝9个月流鼻涕怎么办 鼻涕又黄又粘稠怎么办 鼻子一直流黄水怎么办 宝宝眼屎多又黄怎么办