HDU 2461 Rectangles poj 3695 Rectangles

纯容斥定理:

View Code
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

#include<map>

#include<cstring>

#include<vector>

#include<string>

#define LL long long

using namespace std;

const int INF = 10000;

class Node

{

public:

      int x1,y1,x2,y2;    

}node[24];

int status[1250000],N;

void DFS( int x1 , int y1 , int x2 , int y2 , int deep , int sign, int sta )

{

     if( x1 >= x2 || y1 >= y2 ) return;

     if( deep == N )

     {

         if( sta !=0 )

         for( int i = 1 ; i < 1 << N; i ++ )

         {

              if( (i | sta) <= i )

                  status[i] += sign*( x2 - x1 ) * ( y2 - y1 );        

         }    

         return ;

     }

     DFS( x1 , y1 , x2 , y2 , deep + 1, sign , sta );

     DFS(max(x1,node[deep].x1),max(y1,node[deep].y1),min(x2,node[deep].x2),min(y2,node[deep].y2),deep+1,-sign,sta|(1<<deep));

}

int main(  )

{

    int M,num,n,Case = 1;

    while( scanf( "%d%d",&N,&M ),N|M )

    {

        memset( status , 0  , sizeof( status ) );

        for( int i = 0 ; i < N ; i ++ )

             scanf( "%d%d%d%d",&node[i].x1,&node[i].y1,&node[i].x2,&node[i].y2 );

        DFS( 0 , 0 , INF , INF , 0 , -1 ,0 );

        

        printf( "Case %d:\n",Case++ );

        for( int i = 1 ; i <= M ; i ++ )

        {

           int sta = 0;

           scanf( "%d",&n );

           for( int j = 0 ; j < n ; j ++ )

           {

                scanf( "%d",&num );

                   sta |= 1<< (num-1);  

           }    

           printf( "Query %d: %d\n",i,status[sta] );

        } 

        puts( "" );

    }

    //system( "pause" );

    return 0;

}

优化版:

View Code
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

#include<map>

#include<cstring>

#include<vector>

#include<string>

#define LL long long

using namespace std;

class Node

{

public:

      int x1,y1,x2,y2;

}node[24];

int status[1100000],sta[100024],N,M;

const int INF = 1000;

void DFS( int x1,int y1,int x2,int y2 ,int deep, int s,int sign )

{

     if( x1>=x2 || y1 >= y2 ) return;

     if( deep == N )

     {

         if( s!=0 )

         {

             for( int i = 0; i < M; i ++ )

             {

                  if( (sta[i] | s) <= sta[i] ) {

                    status[sta[i]] += sign*( x2 - x1 )*( y2 - y1 );

                  }

             }        

         }        

         return;

     }    

     DFS( x1 , y1 , x2 , y2 , deep+1, s , sign );

     DFS(max(x1,node[deep].x1),max(y1,node[deep].y1),min(x2,node[deep].x2),min(y2,node[deep].y2),deep+1,s|(1<<deep),-sign);

}

int main(  )

{

    int n,num,Case=1;

    while( scanf("%d%d",&N,&M),N||M )

    {

          for( int i = 0 ; i < N ; i++ )

          {

               scanf( "%d%d%d%d",&node[i].x1,&node[i].y1,&node[i].x2,&node[i].y2);        

          }    

          memset( status, 0 , sizeof( status ) );

          memset( sta, 0 , sizeof( sta ) );

          for( int i = 0 ; i < M ;i ++ )

          {

                  scanf( "%d",&n );

                  for( int j = 0 ; j < n ; j ++ )

                  {

                    scanf( "%d",&num );

                    sta[i] |=1<<(num-1);            

               }

          }

          DFS( 0,0,INF,INF,0,0,-1 );

          printf( "Case %d:\n",Case++ );

          for( int i = 0 ; i < M; i ++ )

          {

               printf( "Query %d: %d\n",i+1,status[sta[i]] );        

          }

          puts("");

    }

    //system( "pause" );

    return 0;

}

 用离散化处理:

View Code
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

#include<map>

#include<cstring>

#include<vector>

#include<string>

#define LL long long

using namespace std;

class Rec

{

public:

      int x1,y1,x2,y2;    

}rec[24],p[24];

int N,M;

bool cmp1( Rec a, Rec b )

{

    return a.y1 < b.y1;

}

bool cmp2( int a, int b )

{

   return a < b;    

}

void Solve( ){

    int num,n,cnt,left[50],right[50],tx[50],count,t;

    for( int k = 1 ; k <= M; k ++ )

    {

        t = 0; count = 0;cnt=0; 

        scanf( "%d",&n );

        for( int i = 0 ; i < n ; i ++ )

        {

            scanf( "%d",&num );

            p[cnt++] = rec[num];

            tx[count++] = rec[num].x1;

            tx[count++] = rec[num].x2;

        }        

        sort( p , p + cnt , cmp1 );

        sort( tx , tx + count , cmp2  );

        for( int i = 1 ; i < count ; i ++ )

        if( tx[i-1]!=tx[i] ) 

        {

            left[t] = tx[i-1];

            right[t++] = tx[i];

//            printf( "%d %d %d\n",left[t-1],right[t-1],t ); 

        }

        int ans = 0;

        for( int i = 0 ; i < t ; i ++ )

        {

            int up = -1 , down = -1;

            for( int j = 0 ; j < cnt ; j ++ )

            {

                if( left[i]>=p[j].x1 && right[i]<=p[j].x2 )

                {

                    if( up < p[j].y1 )

                    {

                        ans += ( right[i] - left[i] )*( up - down );

                        up = p[j].y2; down = p[j].y1; 

                    }

                    else if( up < p[j].y2 )

                             up = p[j].y2; 

                }

            }

                ans +=  ( right[i] - left[i] )*( up - down );

//                printf( "ans=%d %d %d %d\n",ans,up,down,right[i]- left[i] ); 

        }

            printf( "Query %d: %d\n",k,ans ); 

     } 

    }

int main(  )

{

    int Case = 1; 

    while( scanf( "%d%d",&N,&M ),N|M )

    {

         for( int i = 1 ; i <= N ; i ++ )

         {

             scanf( "%d%d%d%d",&rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2 );        

         }    

         printf( "Case %d:\n",Case++ ); 

         Solve( );

         puts( "" ); 

    }

    //system( "pause" );

    return 0;

}

 

你可能感兴趣的:(poj)