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;
}

 

posted @ 2012-07-28 22:48  wutaoKeen  阅读(266)  评论(0编辑  收藏  举报