线段树
还没想好怎么做....
线段切割
主要思想就是保存小球被涂成白色那些区间,最后再合并,遍历一下,找出最长的那段就好了
一开始没想到,就想着怎么用线段树,结果什么都想不到.......
代码参考
http://www.cnblogs.com/183zyz/archive/2010/08/21/1805430.html
#include<iostream>
#include<algorithm>
using namespace std;
#define m 2222
int k;
struct node
{
int s,e;
}e[m];
int cmp(const void *a,const void *b)<span style="white-space:pre"> </span>//不会.....之前指针尽量避免,现在不会写了,该去复习一下了。
{
struct node *c=(node *)a;
struct node *d=(node *)b;
return c->s - d->s;
}
void white()<span style="white-space:pre"> </span>//涂成白色的空间合并
{
qsort(e,k,sizeof(e[0]),cmp);
for(int i=0;i<k;i++)
{
if(e[i-1].s&&e[i-1].e+1>=e[i].s)
{
e[i].s=e[i-1].s;
if(e[i-1].e>e[i].e)
e[i].e=e[i-1].e;
}
}
}
void black(int a,int b)
{
for(int i=0;i<k;i++)
{
if(e[i].s)
{
if(e[i].s<a&&e[i].e>=a&&e[i].e<=b)<span style="white-space:pre"> </span>//左边交叉但不包含
e[i].e=a-1;
else if(e[i].s>=a&&e[i].s<=b&&e[i].e>b)<span style="white-space:pre"> </span>//右边交叉但不包含
e[i].s=b+1;
else if(e[i].s<a&&e[i].e>b)<span style="white-space:pre"> </span>//包含,全涂白
{
e[k].s=b+1;
e[k].e=e[i].e;
e[i].e=a-1;
k++;
}
else if(e[i].s>=a&&e[i].e<=b)<span style="white-space:pre"> </span>//包含,全被涂黑了
e[i].s=0;
}
}
}
int main()
{
int t;
while(scanf("%d",&t)!=EOF)
{
k=0;
int a,b;
char c;
for(int i=0;i<t;i++)
{
scanf("%d %d %c",&a,&b,&c);
if(a>b)<span style="white-space:pre"> </span>//这个很坑的
{
int t=a;a=b;b=t;
}
if(c=='w')
{
e[k].s=a;
e[k].e=b;
k++;
}
else
black(a,b);
}
white();
int j=0,max=0;
for(int i=0;i<k;i++)
{
if(e[i].s)<span style="white-space:pre"> </span>//这个判断除去上面第二种包含的情况
{
if((e[i].e-e[i].s+1)>max)
{
max=e[i].e-e[i].s+1;
j=i;
}
}
}
if(max)printf("%d %d\n",e[j].s,e[j].e);
else printf("Oh, my god\n");
}
return 0;
}