USACO 2.1.1 The Castle

IOI经典原题

题意:一幅城堡中的各个房间,东西南北四个方向都可能会有,没有墙的话视为连通,

求解有多少个连通分量,最大房间的大小是多少,同时,如果移除一个墙,最大的房间面积是多少,

移除墙的位置在哪儿。注意,移除墙的顺序为自南往北,先北面的墙再东面的墙(题意理解上比较麻烦的地方)

 

2.1的TEXT中讲到了flood fill算法,结合DFS和BFS的基本搜索方法

对于本题,先DFS求出所有的连通分量,

然后按照题目的要求,顺序搜索移除的墙的位置,得到最优解(官方的解题思路类似)

提交了3次。。

/*
ID: lsswxr1
PROG: castle
LANG: C++
*/
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
using namespace std;

#define USACO
#ifdef USACO
#define cin fin
#define cout fout
#endif
//////////////////////////////////////////////////////////////////////////
///宏定义
const int  INF = 1000000000;
const int MAXN = 50;
const int maxn = MAXN;
///全局变量 和 函数

int M, N;
struct node
{
    int component;
    int wall;
};
node Nodes[maxn][maxn];

int maxRoom;
int comp;
bool vis[maxn][maxn];
int compSize[maxn * maxn];
void dfs(int curRow, int curCol)
{
    vis[curRow][curCol] = true;
    Nodes[curRow][curCol].component = comp;
    compSize[comp]++;
    //向西搜索
    if (curCol > 0)
    {
        if ((Nodes[curRow][curCol].wall & 0x1) != 0x1)
        {
            if (!vis[curRow][curCol - 1])
                dfs(curRow, curCol - 1);
        }
    }
    //向北搜索
    if (curRow > 0)
    {
        if ((Nodes[curRow][curCol].wall & 0x2) != 0x2)
        {
            if(!vis[curRow - 1][curCol])
                dfs(curRow - 1, curCol);
        }
    }

    //向南搜索
    if (curRow < N - 1)
    {
        if ((Nodes[curRow][curCol].wall & 0x8) != 0x8)
        {
            if (!vis[curRow + 1][curCol])
                dfs(curRow + 1, curCol);
        }
    }

    //向东搜索
    if (curCol < M - 1)
    {
        if ((Nodes[curRow][curCol].wall & 0x4) != 0x4)
        {
            if (!vis[curRow][curCol + 1])
            {
                dfs(curRow, curCol + 1);
            }
        }
    }
}

int maxRemoveSize;
int maxRemoveRow, maxRemoveCol;
char maxRemoveDir;
int main()
{
#ifdef USACO    
    ofstream fout ("castle.out");
    ifstream fin ("castle.in");
#endif   
    while (cin >> M >> N)
    {
        memset(Nodes, 0, sizeof(Nodes));
        memset(vis, false, sizeof(vis));
        memset(compSize, 0, sizeof(compSize));
        maxRoom = -INF;
        maxRemoveSize = -INF;
        comp = 1;
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                int curWall;
                cin >> curWall;
                Nodes[i][j].wall = curWall;
            }
        }

        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                if (!vis[i][j])
                {
                    dfs(i, j);
                    comp++;
                }
            }
        }

        for (int i = 0; i < comp; i++)
            maxRoom = max(maxRoom, compSize[i]);

        maxRemoveSize = maxRoom;
        for (int j = 0; j < M; j++)
        {
            for (int i = N - 1; i >= 0; i--)  //少写了一个等号..
            {

                //移除北面的墙
                if ((i > 0) && ((Nodes[i][j].wall & 0x2) == 0x2))
                {
                    if ((Nodes[i][j].component != Nodes[i - 1][j].component) && (compSize[Nodes[i][j].component] + compSize[Nodes[i - 1][j].component] > maxRemoveSize))
                    {
                        maxRemoveSize = compSize[Nodes[i][j].component] + compSize[Nodes[i - 1][j].component]; //写错了第一个式子
                        maxRemoveDir = 'N';
                        maxRemoveRow = i;
                        maxRemoveCol = j;
                    }
                }
                //移除东面的墙
                if ((j < M - 1) && ((Nodes[i][j].wall & 0x4) == 0x4))
                {
                    if ((Nodes[i][j].component != Nodes[i][j + 1].component) && (compSize[Nodes[i][j].component] + compSize[Nodes[i][j + 1].component] > maxRemoveSize))
                    {
                        maxRemoveSize = compSize[Nodes[i][j].component] + compSize[Nodes[i][j + 1].component];
                        maxRemoveDir = 'E';
                        maxRemoveRow = i;
                        maxRemoveCol = j;
                    }
                }
            }
        }

        cout << comp - 1 << endl;
        cout << maxRoom << endl;
        cout << maxRemoveSize << endl;
        cout << maxRemoveRow + 1 << " " << maxRemoveCol + 1 << " " << maxRemoveDir << endl;
    }
    
    ///结束
    return 0;
}

 

posted on 2014-01-17 11:30  小书包_Ray  阅读(246)  评论(0编辑  收藏  举报

导航