結果
問題 | No.348 カゴメカゴメ |
ユーザー |
![]() |
提出日時 | 2016-02-26 23:47:23 |
言語 | C++11 (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 105 ms / 2,000 ms |
コード長 | 5,317 bytes |
コンパイル時間 | 1,477 ms |
コンパイル使用メモリ | 117,676 KB |
実行使用メモリ | 30,580 KB |
最終ジャッジ日時 | 2024-09-23 03:10:05 |
合計ジャッジ時間 | 4,046 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 53 |
ソースコード
#include <iostream>#include <iomanip>#include <sstream>#include <vector>#include <string>#include <set>#include <unordered_set>#include <map>#include <unordered_map>#include <stack>#include <queue>#include <deque>#include <algorithm>#include <functional>#include <iterator>#include <limits>#include <numeric>#include <utility>#include <cmath>#include <cassert>#include <cstdio>using namespace std;using namespace placeholders;using LL = long long;using ULL = unsigned long long;using VI = vector< int >;using VVI = vector< vector< int > >;using VS = vector< string >;using SS = stringstream;using PII = pair< int, int >;using VPII = vector< pair< int, int > >;template < typename T = int > using VT = vector< T >;template < typename T = int > using VVT = vector< vector< T > >;template < typename T = int > using LIM = numeric_limits< T >;template < typename T > inline istream& operator>>( istream &s, vector< T > &v ){ for ( T &t : v ) { s >> t; } return s; }template < typename T > inline ostream& operator<<( ostream &s, const vector< T > &v ){ for ( int i = 0; i < int( v.size() ); ++i ){ s << ( " " + !i) << v[i]; } return s; }template < typename T > inline T fromString( const string &s ) { T res; istringstream iss( s ); iss >> res; return res; }template < typename T > inline string toString( const T &a ) { ostringstream oss; oss << a; return oss.str(); }#define REP2( i, n ) REP3( i, 0, n )#define REP3( i, m, n ) for ( int i = ( int )( m ); i < ( int )( n ); ++i )#define GET_REP( a, b, c, F, ... ) F#define REP( ... ) GET_REP( __VA_ARGS__, REP3, REP2 )( __VA_ARGS__ )#define FOR( e, c ) for ( auto &&e : c )#define ALL( c ) begin( c ), end( c )#define AALL( a, t ) ( t* )a, ( t* )a + sizeof( a ) / sizeof( t )#define DRANGE( c, p ) ( c ).begin(), ( c ).begin() + ( p ), ( c ).end()#define SZ( v ) ( (int)( v ).size() )#define EXIST( c, e ) ( ( c ).find( e ) != ( c ).end() )template < typename T > inline bool chmin( T &a, const T &b ){ if ( b < a ) { a = b; return true; } return false; }template < typename T > inline bool chmax( T &a, const T &b ){ if ( a < b ) { a = b; return true; } return false; }#define PB push_back#define EM emplace#define EB emplace_back#define BI back_inserter#define MP make_pair#define fst first#define snd second#define DUMP( x ) cerr << #x << " = " << ( x ) << endlint N, M;VS board;VVI G;VI sizes;VVI visited;constexpr bool inside( const int y, const int x ){return 0 <= y && y < N && 0 <= x && x < M;}inline bool throuable( const int y1, const int x1, const int y2, const int x2 ){if ( board[ y2 ][ x2 ] == 'x' ){return false;}const auto mmy = minmax( y1, y2 );const auto mmx = minmax( x1, x2 );int cnt = 0;REP( y, mmy.fst, mmy.snd + 1 ){REP( x, mmx.fst, mmx.snd + 1 ){cnt += board[y][x] == 'x';}}return cnt <= 1;}void dfs( const int sy, const int sx, const int u ){if ( SZ( G ) <= u ){G.resize( u + 1 );sizes.resize( u + 1 );}if ( board[ sy ][ sx ] == 'x' ){ // erase current loopqueue< PII > que;que.EM( sy, sx );int cnt = 0;while ( !que.empty() ){const int y = que.front().fst;const int x = que.front().snd;que.pop();REP( dy, -1, 2 ){REP( dx, -1, 2 ){if ( !( dy | dx ) ){continue;}const int ny = y + dy;const int nx = x + dx;if ( !inside( ny, nx ) || board[ ny ][ nx ] == '.' ){continue;}++cnt;board[ ny ][ nx ] = '.';visited[ ny ][ nx ] = 2;que.EM( ny, nx );}}}sizes[u] = cnt;}VPII nexts;{ // find adjacenta loopsqueue< PII > que;que.EM( sy, sx );while ( !que.empty() ){const int y = que.front().fst;const int x = que.front().snd;que.pop();REP( dy, -1, 2 ){REP( dx, -1, 2 ){if ( !( dy | dx ) ){continue;}const int ny = y + dy;const int nx = x + dx;if ( !inside( ny, nx ) || visited[ ny ][ nx ] ){continue;}if ( board[ ny ][ nx ] == 'x' ){nexts.EB( ny, nx );}if ( throuable( y, x, ny, nx ) ){que.EM( ny, nx );visited[ ny ][ nx ] = true;}}}}}FOR( p, nexts ){const int y = p.fst;const int x = p.snd;if ( visited[y][x] == 2 ){continue;}visited[y][x] = true;G[u].PB( SZ( G ) );dfs( y, x, SZ( G ) );}return;}VVI dp;int rec( const int u, const int f ){int &res = dp[u][f];if ( res != -1 ){return res;}if ( f ) // use current node{int total = sizes[u];FOR( v, G[u] ){total += rec( v, 0 );}chmax( res, total );}{ // do not use current nodeint total = 0;FOR( v, G[u] ){total += max( rec( v, 0 ), rec( v, 1 ) );}chmax( res, total );}return res;}int main(){cin.tie( 0 );ios::sync_with_stdio( false );cin >> N >> M;board.resize( N );cin >> board;board.insert( begin( board ), string( M + 2, '.' ) );REP( i, 1, N + 1 ){board[i] = "." + board[i] + ".";}board.EB( M + 2, '.' );N += 2;M += 2;visited.resize( N, VI( M ) );dfs( 0, 0, 0 );const int V = SZ( sizes );dp.resize( V, VI( 2, -1 ) );cout << rec( 0, 0 ) << endl;return 0;}