[U]3.1.4 Shaping Regions 递归,计算几何

来源:互联网 发布:周思成网络课程 编辑:程序博客网 时间:2024/05/30 04:56

一道很有意思的题目。只是今天的课程比较紧张,中午敲了下题,下午上完课后接着敲了下题。改了些bug,终于还是过了。鼓励一下~

解题思路:

题目大意是矩形覆盖问题,求最终见到的各种颜色矩形的面积。由于矩形比较多1000个而且坐标范围用点阵表示会爆空间。题中给的Hints也是含混不清。在队友提点下,终于到了解决的办法。用递归,因为题中有很明显的子问题性质,当前色块的矩形被上面的矩形覆盖之后可以分割成小矩形,再通过小矩形被更上面的矩形覆盖后进而递推。

由于没有想出用好的方法来表示矩形的碰撞情况,若用枚举的话,考虑情况太多而且代码冗余量太大。

矩形覆盖有3种情况:

1.完全不相交:

2.部分相交:

1.>1个角覆盖;

2.>2个角覆盖;

3.完全被包含(4个角覆盖):

显然枚举太麻烦!!!

考虑一般情况:


这样蓝色矩形就在黄色矩形的切割下分为4个小矩形。

把4个小矩形的坐标定义好,再进行递归。

那么其他情况怎么办呢??


同样的在这种情况下,也分为4个小矩形,明显的S1和S4是不符合条件的。

通过我们的坐标定义可以看出S1.ury<S1.lly 这样明显的翻折过来了,这样的矩形不能用。

而S4.urx<S4.llx,同样这样的矩形也不能用。

这种表达方式把所有的情况都包含在内了?还缺了一种:完全相交的情况!

通过坐标定义可以切出符合题意的矩形。将这种情况滤除掉就好了。

另外细节方面要注意的就是细心,还有就是坐标的问题。urx和ury那个点时没有实心点的。这点要好好注意。

总算是切掉了!

Code:

/*ID:13ysenLANG:C++PROG:rect1*/#include<stdio.h>#include<algorithm>#define MAXR 1001using namespace std;struct node{    int llx,lly,urx,ury;}rect[MAXR];struct Color{    int color;    int cnt;}rec[MAXR];bool cmp( Color a,Color b ){ return a.color<b.color; }int N;int min( int a,int b ){ return a<b?a:b; }int max( int a,int b ){ return a>b?a:b; }bool judge( node a ){  if( a.llx>a.urx || a.lly>a.ury )   return false;  return true;}void recursion( node a,int layer,int index ){  if( judge(a)==false )   return ;  bool recur=false;  for( int i=layer+1;i<=N;i++ )  {    if( a.llx>rect[i].urx || a.lly>rect[i].ury || a.urx<rect[i].llx || a.ury<rect[i].lly )      continue;    recur=true;    node s1,s2,s3,s4;    s1=s2=s3=s4=a;    s1.lly=rect[i].ury+1;    s3.ury=rect[i].lly-1;    s2.urx=rect[i].llx-1;    s4.llx=rect[i].urx+1;    s4.lly=s2.lly=max( rect[i].lly,a.lly );    s4.ury=s2.ury=min( rect[i].ury,a.ury );    recursion( s1,i,index );    recursion( s2,i,index );    recursion( s3,i,index );    recursion( s4,i,index );    break; } if( recur==false )  rec[index].cnt+=(a.urx-a.llx+1)*(a.ury-a.lly+1);  return ;}int main(){ freopen( "rect1.in","r",stdin ); freopen( "rect1.out","w",stdout ); int A,B; scanf( "%d %d %d",&A,&B,&N );  for( int i=0;i<=N;i++ )  rec[i].cnt=rec[i].color=0;rect[0].llx=rect[0].lly=0; rect[0].urx=A-1;rect[0].ury=B-1; rec[0].color=1; for( int i=1;i<=N;i++ ) {  scanf( "%d %d %d %d %d",&rect[i].llx,&rect[i].lly,&rect[i].urx,&rect[i].ury,&rec[i].color ); rect[i].urx-=1; rect[i].ury-=1;}for( int i=0;i<=N;i++ ) recursion( rect[i],i,i );sort( rec,rec+N+1,cmp );    int ans=0;for( int i=0;i<=N;i++ ){  if( rec[i].color==rec[i+1].color )   ans+=rec[i].cnt;  else   { if( rec[i].cnt+ans>0 )     printf( "%d %d\n",rec[i].color,rec[i].cnt+ans );   ans=0;         }    }return 0;}


原创粉丝点击