又是好多天没有写过了,这两天在研究线段树,到现在为止,总算是理解了一些!

这道题目应该是属于简单的离散题,由于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;
}

posted on 2010-08-21 17:22  奋斗青春  阅读(1247)  评论(0编辑  收藏  举报