p2716_线段计算.cpp

来自「高手写的所有acm例程 在acm.zju.edu.cn 上的题目的例程」· C++ 代码 · 共 172 行

CPP
172
字号
#include <stdio.h>
#include <map>
#include <algorithm>
#define MAXN 1000

using namespace std;

const int days [13] = { 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 };

struct TDate {
       int year , month , day;
       bool operator < ( const TDate & ) const;
       bool operator == ( const TDate & ) const; 
       TDate operator + ( const int );
       TDate operator - ( const int );
       void init ();
       void print () const ;
};

typedef map < TDate , int > TMap;

int    N1 , N2 , N , Tot;
TDate  Add1 [MAXN] , Add2 [MAXN] , Sub1 [MAXN] , Sub2 [MAXN] , Info [MAXN] , Start [MAXN] , Finish [MAXN];
TMap   Map;
bool   Line [MAXN] , Point [MAXN];

bool isleap ( int );
bool isgood ( TDate );
bool init ();
void solve ();
bool check ();

main ()
{
     int p = 0;
     for ( ; init (); ) {
         if ( p ) printf ( "\n" );
         printf ( "Case %d:\n" , ++ p );
         solve ();
         if ( !check () ) for (;;);
     }
}

bool check ()
{
     for ( int i = 0; i < N2; i ++ )
         if ( !isgood ( Add1 [i] ) || !isgood ( Add2 [i] ) ) return false;
     for ( int i = 0; i < N1; i ++ )
         if ( !isgood ( Sub1 [i] ) || !isgood ( Sub2 [i] )) return false;
     for ( int i = 0; i < Tot; i ++ )
         if ( !isgood ( Start [i] ) || !isgood ( Finish [i] )) return false;
     return true;
}

void solve ()
{
     int a , b , i , j;
     
     memset ( Line , 0 , sizeof ( Line ));
     memset ( Point , 0 , sizeof ( Point ));
     
     for ( i = 0; i < N2; i ++ ) {
         a = Map [Add1 [i]] , b = Map [Add2 [i]];
         for ( j = a; j < b; j ++ ) Line [j] = Point [j] = true; Point [b] = true;
     }
     for ( i = 0; i < N1; i ++ ) {
         a = Map [Sub1 [i]] , b = Map [Sub2 [i]];
         for ( j = a; j < b; j ++ ) Line [j] = Point [j] = false; Point [b] = false;
     }
     for ( i = 0; i + 1 < N; i ++ )
         if ( Info [i] + 1 == Info [i + 1] ) Line [i] = true;
     
     
//     for ( int i = 0; i < N; i ++ ) printf ( "%d " ,Line [i] ); printf ("\n" );
//     for ( int i = 0; i < N; i ++ ) printf( "%d " , Point [i] ); printf ("\n" );
     
     for ( i = Tot = 0; i < N; i ++ ) if ( Point [i] || Line [i] ) {
         if ( Point [i] ) Start [Tot] = Info [i]; else Start [Tot] = Info [i] + 1;
         Point [i] = true;
         for ( ; Point [i] && Line [i]; i ++ );
         if ( Point [i] ) Finish [Tot ++] = Info [i]; else Finish [Tot ++] = Info [i] - 1;
         if ( Finish [Tot - 1] < Start [Tot - 1] ) Tot --;
         Point [i --] = false;
     }
     for ( i = 0; i < Tot; i ++ ) {
         if ( Start [i] == Finish [i] ) Start [i].print ();
         else Start [i].print () , printf ( " to " ) , Finish [i].print ();
         printf ( "\n" );
     }
     if ( Tot == 0 ) printf ( "No additional quotes are required.\n" );
}

bool init ()
{
     scanf ( "%d%d" , &N1 , &N2 ); 
     if ( N1 == 0 && N2 == 0 ) return false;
     
     N = 0;
     for ( int i = 0; i < N1; i ++ ) Sub1 [i].init () , Sub2 [i].init () , Info [N ++] = Sub1 [i] , Info [N ++] = Sub2 [i];
     for ( int i = 0; i < N2; i ++ ) Add1 [i].init () , Add2 [i].init () , Info [N ++] = Add1 [i] , Info [N ++] = Add2 [i];
     
     sort ( Info , Info + N ) , N = unique ( Info , Info + N ) - Info;
     
     Map.clear ();
//     for ( int i = 0; i < N;i ++ ) Info [i].print (), printf ( "\n" );
     for ( int i = 0; i < N; i ++ ) Map [Info [i]] = i;
     
     return true;
}

bool isleap ( int year )
{
     return year % 100 == 0 ? year % 400 == 0 : year % 4 == 0;
}

bool TDate :: operator < ( const TDate & Cmp ) const {
     if ( year != Cmp.year ) return year < Cmp.year;
     if ( month != Cmp.month ) return month < Cmp.month;
     return day < Cmp.day;
}

bool TDate :: operator == ( const TDate & Cmp ) const {
     return year == Cmp.year && month == Cmp.month && day == Cmp.day;
}

void TDate :: init ()
{
     int Tmp;
     scanf ( "%d" , &Tmp );
     year = Tmp / 10000 , month = Tmp / 100 % 100 , day = Tmp % 100;
}

void TDate :: print () const
{
     printf ( "%d/%d/%d" , month , day , year );
}

TDate TDate :: operator + ( const int d )
{
      TDate Ret = *this;
      Ret.day ++;
      if ( Ret.day <= days [Ret.month] || Ret.day == 29 && Ret.month == 2 && isleap ( Ret.year ));
      else Ret.day = 1 , Ret.month ++;
      if ( Ret.month == 13 ) Ret.year ++ , Ret.month = 1;
      if ( d > 1 ) Ret = Ret + ( d - 1 );
      return Ret;
}

TDate TDate :: operator - ( const int d )
{
      TDate Ret = *this;
      Ret.day --;
      if ( Ret.day == 0 ) { 
           Ret.month --; 
           if ( Ret.month == 0 ) 
              Ret.year -- , Ret.month = 12; 
           Ret.day = days [Ret.month]; 
           if ( Ret.month == 2 && isleap ( Ret.year )) Ret.day ++; 
      }
      if ( d > 1 ) Ret = Ret - ( d - 1 );
      return Ret;
}

bool isgood ( TDate B )
{
     if ( B.year < 1700 || B.year > 2100 ) return false;
     if ( B.month < 1 || B.month > 12 ) return false;
     if ( B.day >= 1 && B.day <= days [B.month] ) return true;
     if ( B.month == 2 && isleap ( B.year ) && B.day == 29 ) return true;
     return false;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?