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;
}
时间: 2024-10-10 05:37:39

USACO Section 2.1 The Castle的相关文章

USACO Section 2.1 Healthy Holsteins

/* ID: lucien23 PROG: holstein LANG: C++ */ #include <iostream> #include <fstream> #include <vector> using namespace std; bool compFun(int x, int y) { int temp, i = 0; while (true) { temp = 1 << i; if (temp&x > temp&y) {

USACO Section 2.2 Party Lamps

/* ID: lucien23 PROG: lamps LANG: C++ */ /* * 此题的技巧之处就是需要注意到任何button只要按下2的倍数次就相当于没有按 * 所以其实只需要考虑4个按钮,每个按钮是否被有效按下过一次就好 * 直接使用枚举法,一共只有2^4=16种情况 * 对于每种情况需要知道被按下的有效次数(也就是被按下过的按钮数),必须满足 * (C-有效次数)%2=0才行,这样其他次数才能视为无效 * 然后验证各种情况是否符合要求,将符合要求的情况按序输出即可 */ #inc

USACO Section 2.2 Runaround Numbers

/* ID: lucien23 PROG: runround LANG: C++ */ #include <iostream> #include <fstream> #include <cstring> using namespace std; int main() { ifstream infile("runround.in"); ofstream outfile("runround.out"); if(!infile || !

USACO Section 2.2 Preface Numbering

/* ID: lucien23 PROG: preface LANG: C++ */ #include <iostream> #include <fstream> #include <string> #include <map> using namespace std; int main() { ifstream infile("preface.in"); ofstream outfile("preface.out")

USACO 2.1.1 The Castle

{ ID:anniel11 PROG:castle LANG:PASCAL } var a:array[0..50,0..50 ,1..4] of boolean; component:array[0..50,0..50] of integer;//which room does it belong to room_size:array[0..2500] of integer; neighbour:array[0..2500,0..2500] of boolean; m,n,i,j,temp,c

USACO Section 2.1 Sorting a Three-Valued Sequence

/* ID: lucien23 PROG: sort3 LANG: C++ */ #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; void exchange(int nums[], int begin, int end, int N, int x); int sum = 0; int main() { ifst

USACO Section 1.1 Your Ride Is Here

原题: Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs often come to collect loyal supporters from here on Earth. Unfortunately, they only have room to pick up one group of followers on each trip. They do, how

[IOI1996] USACO Section 5.3 Network of Schools(强连通分量)

nocow上的题解很好. http://www.nocow.cn/index.php/USACO/schlnet 如何求强连通分量呢?对于此题,可以直接先用floyd,然后再判断. ---------------------------------------------------------------------------------- #include<cstdio> #include<iostream> #include<algorithm> #includ

USACO Section 5.3 Big Barn(dp)

USACO前面好像有类似的题目..dp(i,j)=min(dp(i+1,j),dp(i+1,j+1),dp(i,j+1))+1  (坐标(i,j)处无tree;有tree自然dp(i,j)=0) .dp(i,j)表示以坐标(i,j)为左上角的barn边长最大值,dp(i+1,j),dp(i,j+1)分别表示向右和向下能扩展的最大边长,但是以此为正方形时,右下方的一个格子没有考虑到,所以就+个dp(i+1,j+1).边界为:dp(i,j)=1(i==n-1或j==n-1). -----------