又是好多天没有写过了,这两天在研究线段树,到现在为止,总算是理解了一些!
这道题目应该是属于简单的离散题,由于a,b可能会非常的大,我没有想到怎么用线段树来做,就参考了一下别人的代码!
大致的题意是这样的,有很多个小球从1开始标号,开始的时候颜色均为黑色,然后进行n次操作,每次输入两个数a,b(表示标号),然后再输入一个字符c,c可能为‘w’和‘b’其中的一个,‘w’表示把a,b之间的小球涂成白色,‘b’表示涂成黑色;最后 输出longest white ball sequence的左边界和右边界!
code:
# include<stdio.h> # include<stdlib.h> struct node{ int start,end; }s[2004]; int k; int cmp(const void *a ,const void*b) { struct node *c=(node *)a; struct node *d=(node *)b; return c->start - d->start; } void white() { qsort(s,k,sizeof(s[0]),cmp); for(int i=1;i<k;i++) { if(s[i-1].start && s[i-1].end+1>=s[i].start) { s[i].start=s[i-1].start; if(s[i-1].end> s[i].end) s[i].end=s[i-1].end; } } } void black(int a,int b) { for(int i=0;i<k;i++) { if(s[i].start) { if(s[i].start< a && s[i].end>=a && s[i].end<=b) s[i].end=a-1; else if(s[i].start>=a && s[i].start<=b && s[i].end>b) s[i].start=b+1; else if(s[i].start<a && s[i].end>b) { s[k].start=b+1; s[k].end=s[i].end; s[i].end=a-1; k++; } else if(s[i].start>=a && s[i].end<=b) s[i].start=0; } } } int main() { int i,j,n,b,a,max,t; char c; while(scanf("%d",&n)!=-1) { k=0; while(n--) { scanf("%d%d %c",&a,&b,&c); if(a>b){t=a;a=b;b=t;} if(c=='w') { s[k].start=a; s[k].end=b; k++; } else black(a,b); } white(); max=0; j=0; for(i=0;i<k;i++) { if(s[i].start) { if((s[i].end-s[i].start+1) > max) { max=s[i].end-s[i].start+1; j=i; } } } if(max) printf("%d %d\n",s[j].start,s[j].end); else printf("Oh, my god\n"); } return 0; }