T1
原題可以轉化爲:
給出一個圖
分析
對每個點搜索,此時染色爲X,則相鄰點染色爲X
上代碼
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std ;
const int N = 1e4 + 5 ;
int n, m, ans ;
int cnt[ 2 ], inq[ N ] ; // 染色情況
vector < int > edge[ N ] ;
void init() {
memset( inq , 0xff , sizeof( inq ) ) ;
scanf( "%d %d", &n, &m ) ;
for ( int i = 1 ; i <= m ; i ++ ) {
int a, b ; scanf( "%d %d", &a, &b ) ;
edge[ a ].push_back( b ) ;
edge[ b ].push_back( a ) ;
}
}
// dfs染色,一個顏色的相對顏色爲這個顏色 xor 1
bool dfs( int a , int b ) {
inq[ a ] = b ; cnt[ b ] ++ ;
for ( int i = 0 ; i < edge[ a ].size() ; i ++ ) {
int node = edge[ a ][ i ] ;
if ( inq[ node ] == -1 )
if ( !dfs( node , b ^ 1 ) )
return false ;
else
continue ;
else
if ( inq[ node ] == b )
return false ;
else
continue ;
}
return true ;
}
bool figure() {
for ( int i = 1 ; i <= n ; i ++ )
if ( inq[ i ] == -1 && edge[ i ].size() ) { // 是否可進行染色
cnt[ 0 ] = cnt[ 1 ] = 0 ;
if ( !dfs( i , 1 ) ) return false ;
else ans += min( cnt[ 0 ] , cnt[ 1 ] ) ;
}
return true ;
}
int main() {
init() ;
if ( figure() )
printf( "%d\n", ans ) ;
else
printf( "Impossible\n" ) ;
return 0 ;
}
T2
一個表(
分析
對於每一個點,沒有標記過,就搜索,擴張(先橫向擴張,再縱向擴張),並標記新點。擴張的時候注意返回“Bad placement”的情況。(本來覺得應該會T)
上代碼(這道題寫得挫,勿怪)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
const int N = 1e3 + 5 ;
int n, m, cnt ;
int plat[ N ][ N ] ;
void init() {
char ss[ N ] ;
scanf( "%d %d", &n, &m ) ;
for ( int i = 1 ; i <= n ; i ++ ) {
scanf( "%s", ss + 1 ) ;
for ( int j = 1 ; j <= m ; j ++ )
if ( ss[ j ] == '.' )
plat[ i ][ j ] = -1 ;
else
plat[ i ][ j ] = 0 ;
}
}
bool go_row( int &a , int &b , int c ) {
while ( a > 1 && !plat[ a - 1 ][ c ] ) a -- ;
while ( b < n && !plat[ b + 1 ][ c ] ) b ++ ;
if ( plat[ a - 1 ][ c ] != -1 && a > 1 ) return false ;
if ( plat[ b + 1 ][ c ] != -1 && b < n ) return false ;
return true ;
}
int judge( int a , int b , int c ) {
if ( c <= 0 ) return 0 ;
if ( c > m ) return 0 ;
int flag = 0 ;
for ( int i = a ; i <= b ; i ++ )
switch ( plat[ i ][ c ] ) {
case -1 :
if ( !flag ) flag = 1 ;
break ;
case 0 :
continue ;
default :
return -1 ;
}
if ( flag ) return 0 ;
else return 1 ;
}
bool go_col( int a , int b , int &c , int &d ) {
int temp = 0 ;
while ( temp = judge( a , b , c - 1 ), temp == 1 ) c -- ;
if ( temp == -1 ) return false ;
while ( temp = judge( a , b , d + 1 ), temp == 1 ) d ++ ;
if ( temp == -1 ) return false ;
return true ;
}
bool search( int a , int b , int c , int d ) {
if ( !go_row( a , b , c ) ) return false ;
if ( !go_col( a , b , c , d ) ) return false ;
cnt ++ ;
for ( int i = a ; i <= b ; i ++ )
for ( int j = c ; j <= d ; j ++ )
plat[ i ][ j ] = cnt ;
return true ;
}
bool figure() {
for ( int i = 1 ; i <= n ; i ++ )
for ( int j = 1 ; j <= m ; j ++ )
if ( !plat[ i ][ j ] )
if ( !search( i , i , j , j ) )
return false ;
return true ;
}
int main() {
init() ;
if ( figure() )
printf( "There are %d ships.\n", cnt ) ;
else
printf( "Bad placement.\n" ) ;
return 0 ;
}
T3
多個點,向上下左右擴張,問到目標點,需要多少步,裸BFS,多個點都入隊就好了。
分析
一開始多個點入隊,dist = 0, book = true,BFS到所有點就好了。
上代碼
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std ;
const int N = 500 + 2 ;
const int DIR[ 4 ][ 2 ] = { { -1 , 0 } , { 1 , 0 } ,
{ 0 , -1 } , { 0 , 1 } } ;
int n, m, c1, c2 ;
#define Dist( a ) dist[ a.x ][ a.y ]
#define Book( a ) book[ a.x ][ a.y ]
int dist[ N ][ N ] ;
bool book[ N ][ N ] ;
struct node {
int x, y ;
inline node move( int to ) {
node a = (node){ x + DIR[ to ][ 0 ] , y + DIR[ to ][ 1 ] } ;
return a ;
}
} ;
queue < node > Q ;
inline bool judge( node a ) {
if ( a.x >= 1 && a.x <= n )
if ( a.y >= 1 && a.y <= m )
return true ;
return false ;
}
void bfs() {
while ( !Q.empty() ) {
node temp = Q.front() ; Q.pop() ;
for ( int i = 0 ; i < 4 ; i ++ ) {
node nown = temp.move( i ) ;
if ( judge( nown ) && !Book( nown ) ) {
Dist( nown ) = Dist( temp ) + 1 ;
Book( nown ) = true ; Q.push( nown ) ;
}
}
}
}
int main() {
scanf( "%d %d %d %d", &n, &m, &c1, &c2 ) ;
for ( int i = 1 ; i <= c1 ; i ++ ) {
int a, b ; scanf( "%d %d", &a, &b ) ;
Q.push( (node){ a , b } ) ;
dist[ a ][ b ] = 0 ; book[ a ][ b ] = true ;
} bfs() ;
for ( int i = 1 ; i <= c2 ; i ++ ) {
int a, b ; scanf( "%d %d", &a, &b ) ;
printf( "%d\n", dist[ a ][ b ] ) ;
}
return 0 ;
}
以上