USACO/castle

USACO/castle

Posted by dym on February 6, 2014

本文迁移自老博客,原始链接为 https://seven.blog.ustc.edu.cn/usacocastle/

求矩形城堡有多少个房间,每个房间有多大。要把一面单独的墙(指两个单位间的墙)拆掉以形成一个更大的房间,则移除哪面墙可以得到面积最大的新房间且最大面积为多少。 思路:使用dfs判断连通分量的个数并染色,然后根据着色情况枚举得出可去除的墙 要求:选择墙时注意有优先顺序

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <map>
using namespace std;

struct castle {
	bool visited;
	int num;
	int wall;
	int color;
};
int m, n, Max;
int counter, color;
int nmax, ni, nj, nk;
map<int, int> mark;
castle cnt[51][51];
void wall(int wall , bool iswall[]) {
	if (wall & 1)
		iswall[0] = false;
	if (wall & 2)
		iswall[1] = false;
	if (wall & 4)
		iswall[2] = false;
	if (wall & 8)
		iswall[3] = false;
}
void dfs(int i, int j) {
	counter++;
	bool iswall[4] = { true, true, true, true };
	cnt[i][j].visited = true;
	cnt[i][j].color = color;
	wall(cnt[i][j].wall , iswall);
	for (int k = 0; k < 4; k++) {
		if (iswall[k]) {
			if (k == 0  && !cnt[i][j - 1].visited)
				dfs(i, j - 1);
			if (k == 1  && !cnt[i - 1][j].visited)
				dfs(i - 1, j);
			if (k == 2  && !cnt[i][j + 1].visited)
				dfs(i, j + 1);
			if (k == 3  && !cnt[i + 1][j].visited)
				dfs(i + 1, j);
		}
	}
}
int main() {
	ofstream fout ("castle.out");
	ifstream fin ("castle.in");
	fin >> n >> m;
	color = 0;
	Max = 0;
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++) {
			fin >> cnt[i][j].wall;
			cnt[i][j].visited = false;
			cnt[i][j].num = 0;
		}
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++) {
			counter = 0;
			if (!cnt[i][j].visited) {
				dfs(i, j);
				mark[color] = counter;
				if (Max < counter)
					Max = counter;
				color++;
			}

		}
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cnt[i][j].num = mark[cnt[i][j].color];
	nmax = 0;
	int temp;
	for (int j = 0; j < n; j++)
        for (int i = m - 1; i >= 0; i--)
        {
		bool iswall[4] = { true, true, true, true };
		wall(cnt[i][j].wall , iswall);
		for (int k = 0; k < 4; k++) {
			if (!iswall[k]) {
				if (k == 0  && j - 1 >= 0 &&cnt[i][j - 1].color != cnt[i][j].color) {
					temp = cnt[i][j].num + cnt[i][j - 1].num;
					if (temp > nmax) {
						nmax = temp;
						ni = i + 1;
						nj = j + 1;
						nk = k;
					}
				}
				if (k == 1 && i - 1 >= 0 && cnt[i - 1][j].color != cnt[i][j].color) {
					temp = cnt[i][j].num + cnt[i - 1][j].num;
					if (temp > nmax) {
						nmax = temp;
						ni = i + 1;
						nj = j + 1;
						nk = k;
					}
				}
				if (k == 2 && j + 1 < n && cnt[i][j + 1].color != cnt[i][j].color) {
					temp = cnt[i][j].num + cnt[i][j + 1].num;
					if (temp > nmax) {
						nmax = temp;
						ni = i + 1;
						nj = j + 1;
						nk = k;
					}
				}
				if (k == 3 && i + 1 < m &&cnt[i + 1][j].color != cnt[i][j].color) {
					temp = cnt[i][j].num + cnt[i + 1][j].num;
					if (temp > nmax) {
						nmax = temp;
						ni = i + 1;
						nj = j + 1;
						nk = k;
					}
				}
			}
		}
	}
	fout<<color<<endl<<Max<<endl<<nmax<<endl<<ni<<" "<<nj<<" ";
	if(nk == 0)
	    fout<<"W"<<endl;
	else if(nk == 1)
	    fout<<"N"<<endl;
	else if(nk == 2)
            fout<<"E"<<endl;
	else
	    fout<<"S"<<endl;
	return 0;
}