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