USACO Training Section 2.1 The Castle

英文原题  中文题译 

用深度优先或者别的搜索得到连通片(同一连通片的格子属于同一房间),由此得到房间数量(连通分量个数)和最大房间(最大连通分量的节点数)。然后再次扫描整个方格矩阵,注意每个方格有四个相邻房间(东南西北),只需扫描一半方向即可,根据题意,选择东、北方向搜索,这样得到的房间和方向可直接输出无需判重。

WA了一次,原因:把visited标志放在出栈时设导致重复访问使得得到的房间数计数错误。

/*
ID: blackco3
TASK: castle
LANG: C++
*/
#include <fstream>
using namespace std;
#define _max_ 50

int n_row, n_col, n_room, max_room_size=0 ;
int walls[_max_][_max_], room_no[_max_][_max_], visited[_max_][_max_], room_size[_max_*_max_] ;
struct t_cell {
	int row, col ;
} dfs_stk[_max_*_max_];
int adj_mark[4]={1,2,4,8};
int drow[4]={0,-1,0,1}, dcol[4]={-1,0,1,0};
void get_group(int row_no, int col_no, int croom) {
	t_cell *top=dfs_stk ;
	top->row=row_no, top->col=col_no, top++ ;
	room_size[croom]=0, visited[row_no][col_no]=1 ;
	do{
		--top, room_size[croom]++ ;
		int crow=top->row, ccol=top->col;
		room_no[crow][ccol]=croom;
		for( int adj=0; adj<4; adj++ ){
			if( walls[crow][ccol] & adj_mark[adj] || visited[crow+drow[adj]][ccol+dcol[adj]] )
				continue ;
			top->row=crow+drow[adj], top->col=ccol+dcol[adj] ;
			visited[top->row][top->col]=1, top++ ;
		}
	}while( top!=dfs_stk );
	if( max_room_size < room_size[croom] )
		max_room_size = room_size[croom] ;
}

int main()
{	
	ifstream fin("castle.in");
	ofstream fout("castle.out");
	fin >> n_col >> n_row ;
	int irow, icol ;
	for( irow=0; irow<n_row; irow++){
		for( icol=0; icol<n_col; icol++ ){
			fin >> walls[irow][icol] ;
			room_no[irow][icol]=-1, visited[irow][icol]=0 ;
		}
	}
	for( irow=0, n_room=0; irow<n_row; irow++){
		for( icol=0; icol<n_col; icol++ ){
			if( room_no[irow][icol]!=-1 )
				continue ;
			get_group(irow, icol, n_room++);
		}
	}
	fout << n_room << endl << max_room_size << endl ;
	int max_merge=0, mrow, mcol, mwall;
	for( irow=0; irow<n_row; irow++){
		for( icol=0; icol<n_col; icol++ ){
			for( int adj=1; adj<3; adj++ ){
				int adj_row=irow+drow[adj], adj_col=icol+dcol[adj];
				if( adj_row<0 || adj_col>=n_col || room_no[adj_row][adj_col]==room_no[irow][icol] )
					continue ;
				int merge_size = room_size[room_no[adj_row][adj_col]] + room_size[room_no[irow][icol]];
				if( max_merge > merge_size )
					continue ;
				if( max_merge < merge_size ){
					max_merge=merge_size, mrow=irow, mcol=icol, mwall=adj ;
				} else {
					if( mcol>icol || ( mcol==icol && mrow<irow ) )
						mrow=irow, mcol=icol, mwall=adj ;
				}
			}
		}
	}
	fout << max_merge << endl ;
	fout << mrow+1 << " " << mcol+1 << " " << (mwall==1 ? "N" : "E") << endl ;
	return 0;
}

你可能感兴趣的:(C++,c,C#,asp)