首页 > 代码库 > USACO Section 2.1 The Castle

USACO Section 2.1 The Castle

/*
ID: lucien23
PROG: castle
LANG: C++
*/
/************************************************************************/
/* 求图的连通域问题,利用广度扫描                                                       */
/************************************************************************/
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <queue>
using namespace std;

typedef struct Position
{
	int row;
	int col;
	Position(){}
	Position (int r, int c)
	{
		row = r;
		col = c;
	}
} Position;
bool isPrior(Position pos1, char direction1, Position pos2, char direction2);
int main()
{
	ifstream infile("castle.in");
	ofstream outfile("castle.out");
	if(!infile || !outfile)
	{
		cout << "file operation failure!" << endl;
		return -1;
	}


	int M, N;
	infile >> M >> N;
	int ***walls = new int**[N];
	for (int i=0; i<N; i++) 
	{
		walls[i] = new int*[M];
		for (int j = 0; j < M; j++)
		{
			walls[i][j] = new int[6]();
			infile >> walls[i][j][0];
			switch (walls[i][j][0])
			{
			case 0:
				break;
			case 1:
				walls[i][j][1] = 1;
				break;
			case 2:
				walls[i][j][2] = 1;
				break;
			case 3:
				walls[i][j][1] = 1;
				walls[i][j][2] = 1;
				break;
			case 4:
				walls[i][j][3] = 1;
				break;
			case 5:
				walls[i][j][1] = 1;
				walls[i][j][3] = 1;
				break;
			case 6:
				walls[i][j][2] = 1;
				walls[i][j][3] = 1;
				break;			
			case 7:
				walls[i][j][1] = 1;
				walls[i][j][2] = 1;
				walls[i][j][3] = 1;
				break;
			case 8:
				walls[i][j][4] = 1;
				break;
			case 9:
				walls[i][j][1] = 1;
				walls[i][j][4] = 1;
				break;
			case 10:
				walls[i][j][2] = 1;
				walls[i][j][4] = 1;
				break;
			case 11:
				walls[i][j][1] = 1;
				walls[i][j][2] = 1;
				walls[i][j][4] = 1;
				break;
			case 12:
				walls[i][j][3] = 1;
				walls[i][j][4] = 1;
				break;
			case 13:
				walls[i][j][1] = 1;
				walls[i][j][3] = 1;
				walls[i][j][4] = 1;
				break;
			case 14:
				walls[i][j][2] = 1;
				walls[i][j][3] = 1;
				walls[i][j][4] = 1;
				break;
			case 15:
				walls[i][j][1] = 1;
				walls[i][j][2] = 1;
				walls[i][j][3] = 1;
				walls[i][j][4] = 1;
				break;
			default:
				break;
			}
		}
	}

	vector<int> components;
	int cnt = 0;
	for (int i=0; i<N; i++)
	{
		for (int j=0; j<M; j++)
		{
			if (walls[i][j][5] == 0)
			{
				cnt++;
				components.push_back(0);
				queue<Position> nodes;
				nodes.push(Position(i, j));
				while (!nodes.empty())
				{
					Position pos = nodes.front();
					int m = pos.row;
					int n = pos.col;
					int *currentNode = walls[m][n];
					nodes.pop();
					if (currentNode[5] != 0)
						continue;
					components[cnt-1]++;

					currentNode[5] = cnt;
					if (currentNode[1] == 0 && walls[m][n-1][5] == 0)
					{
						nodes.push(Position(m ,n-1));
					}
					if (currentNode[2] == 0 && walls[m-1][n][5] == 0)
					{
						nodes.push(Position(m-1, n));
					}
					if (currentNode[3] == 0 && walls[m][n+1][5] == 0)
					{
						nodes.push(Position(m, n+1));
					}
					if (currentNode[4] == 0 && walls[m+1][n][5] == 0)
					{
						nodes.push(Position(m+1, n));
					}
				}
			}
		}
	}

	int newRoom = 0;
	Position wallPos;
	char dirction;

	for (int i=0; i<N; i++)
	{
		for (int j=0; j<M; j++)
		{
			if (walls[i][j][1] == 1 && j-1>=0 && walls[i][j][5] != walls[i][j-1][5])
			{
				int sum = components[walls[i][j][5]-1] + components[walls[i][j-1][5]-1];
				Position newPos = Position(i, j-1);
				if (sum > newRoom || (sum == newRoom && isPrior(newPos, 'E', wallPos, dirction)))
				{
					newRoom = sum;
					wallPos = newPos;
					dirction = 'E';
				}
			}

			if (walls[i][j][2] == 1 && i-1>=0 && walls[i][j][5] != walls[i-1][j][5])
			{
				int sum = components[walls[i][j][5]-1] + components[walls[i-1][j][5]-1];
				Position newPos = Position(i, j);
				if (sum > newRoom || (sum == newRoom && isPrior(newPos, 'N', wallPos, dirction)))
				{
					newRoom = sum;
					wallPos = newPos;
					dirction = 'N';
				}
			}

			if (walls[i][j][3] == 1 && j+1<M && walls[i][j][5] != walls[i][j+1][5])
			{
				int sum = components[walls[i][j][5]-1] + components[walls[i][j+1][5]-1];
				Position newPos = Position(i, j);
				if (sum > newRoom || (sum == newRoom && isPrior(newPos, 'E', wallPos, dirction)))
				{
					newRoom = sum;
					wallPos = newPos;
					dirction = 'E';
				}
			}

			if (walls[i][j][4] == 1 && i+1<N && walls[i][j][5] != walls[i+1][j][5])
			{
				int sum = components[walls[i][j][5]-1] + components[walls[i+1][j][5]-1];
				Position newPos = Position(i+1, j);
				if (sum > newRoom || (sum == newRoom && isPrior(newPos, 'N', wallPos, dirction)))
				{
					newRoom = sum;
					wallPos = newPos;
					dirction = 'N';
				}
			}
		}
	}

	int maxRoom = components[0];
	for (int i=1; i<cnt; i++)
	{
		if (components[i] > maxRoom)
			maxRoom = components[i];
	}
	outfile << cnt << endl << maxRoom << endl << newRoom << endl 
			   << wallPos.row+1 << " " << wallPos.col+1 << " " << dirction <<endl;

	return 0;
}

bool isPrior(Position pos1, char direction1, Position pos2, char direction2)
{
	if(pos1.col < pos2.col || (pos1.col == pos2.col && pos1.row > pos2.row)
		|| (pos1.col == pos2.col && pos1.row == pos2.row && direction1 == 'N' && direction2 == 'E'))
	{
		return true;
	}
	return false;
}

USACO Section 2.1 The Castle