Count the Colors
来源:互联网 发布:初中网络课程哪家好 编辑:程序博客网 时间:2024/06/05 08:05
Your task is counting the segments of different colors you can see at last.
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.
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.
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
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
- 【線段樹】Count the Colors
- Count the colors
- ZOJ1610-Count the Colors
- zoj1610-Count the Colors
- ZOJ1610 Count the Colors
- Count the Colors
- Count the Colors
- Count the Colors
- F - Count the Colors
- Count the Colors
- zju1610 Count the Colors
- ZOJ1610-Count the Colors
- Count the Colors
- Count the Colors ZOJ
- Count the Colors ZOJ
- Count the Colors ZOJ
- Count the Colors
- Count the Colors(暴力)
- string库之模拟实现strcmp、strncmp和memcmp
- Unity5.x AssetBundle 的变化
- Cookie实现 购物车
- 一切,从这里,这一刻,新的开始
- java 实现设计模式之单例模式(饱汉模式和饿汉模式)
- Count the Colors
- Python学习笔记(一)——Python基础
- Gradient Tree Boosting (GBM, GBRT, GBDT, MART)算法解析和基于XGBoost/Scikit-learn的实现
- 【solr】solr6.4.1安装部署至tomcat教程
- CodeVS2488 绿豆蛙的归宿(第200篇文章纪念)
- 6-假链接
- 7-a标签的锚点功能
- 8-列表标签
- 9-table表格标签及属性