1. 程式人生 > >農場灌溉問題(回溯)

農場灌溉問題(回溯)

題目:

時限:1000ms 記憶體限制:10000K  總時限:3000ms

描述

一農場由圖所示的十一種小方塊組成,藍色線條為灌溉渠。若相鄰兩塊的灌溉渠相連則只需一口水井灌溉。

輸入

給出若干由字母表示的最大不超過50×50具體由(m,n)表示,的農場圖

輸出

程式設計求出最小需要打的井數。每個測例的輸出佔一行。當M=N=-1時結束程式。

輸入樣例

2 2 DK HF 3 3 ADC FJK IHE -1 -1

輸出樣例

2 3

提示

參考迷宮問題,實現時關鍵要解決好各塊的表示問題

思路:將每個塊轉化成左邊的形式,如果兩個塊的上下左右可以接在一起,就將兩個塊合併。

程式碼;

#include <iostream>

using namespace std;

struct node
{
    char ch;
    int visit;
    int left,right,up,down;
}maze[100][100];

int n,m;
int dir[4][2] = {{1,0},{-1,0},{0,-1},{0,1}};

bool place(int x,int y,int nx,int ny)
{
    if(nx > 0 && nx <= m && ny > 0 && ny <= n && !maze[nx][ny].visit)
    {
        if(nx == x && ny == y - 1 && maze[x][y].left && maze[nx][ny].right)
            return 1;
        if(nx == x && ny == y + 1 && maze[x][y].right && maze[nx][ny].left)
            return 1;
        if(nx == x - 1 && ny == y && maze[x][y].up && maze[nx][ny].down)
            return 1;
        if(nx == x + 1 && ny == y && maze[x][y].down && maze[nx][ny].up)
            return 1;
    }
    return 0;
}

void dfs(int x,int y)
{
    maze[x][y].visit = 1;
    for(int i = 0;i < 4;i ++)
    {
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        if(place(x,y,nx,ny))
            dfs(nx,ny);
    }
}

int main()
{
    while(cin >> m >> n && (m != -1 && n != -1))
    {
        int cnt = 0;
        for(int i = 1;i <= m;i ++)
        {
            for(int j = 1;j <= n;j ++)
            {
                cin >> maze[i][j].ch;
                maze[i][j].visit = 0;
                maze[i][j].down = 0;
                maze[i][j].up = 0;
                maze[i][j].right = 0;
                maze[i][j].left = 0;
                if(maze[i][j].ch == 'A')
                    maze[i][j].up = maze[i][j].left = 1;
                else if(maze[i][j].ch == 'B')
                    maze[i][j].up = maze[i][j].right = 1;
                else if(maze[i][j].ch == 'C')
                    maze[i][j].left = maze[i][j].down = 1;
                else if(maze[i][j].ch == 'D')
                    maze[i][j].right = maze[i][j].down = 1;
                else if(maze[i][j].ch == 'E')
                    maze[i][j].down = maze[i][j].up = 1;
                else if(maze[i][j].ch == 'F')
                    maze[i][j].right = maze[i][j].left = 1;
                else if(maze[i][j].ch == 'G')
                    maze[i][j].right = maze[i][j].left = maze[i][j].up = 1;
                else if(maze[i][j].ch == 'H')
                    maze[i][j].up = maze[i][j].down = maze[i][j].left = 1;
                else if(maze[i][j].ch == 'I')
                    maze[i][j].left = maze[i][j].right = maze[i][j].down = 1;
                else if(maze[i][j].ch == 'J')
                    maze[i][j].up = maze[i][j].down = maze[i][j].right = 1;
                else if(maze[i][j].ch == 'K')
                    maze[i][j].up = maze[i][j].down = maze[i][j].right = maze[i][j].left = 1;
            }
        }
        for(int i = 1;i <= m;i ++)
        {
            for(int j = 1;j <= n;j ++)
            {
                if(!maze[i][j].visit)
                    {
                        dfs(i,j);
                        cnt ++;
                    }
            }
        }
        cout << cnt << endl;
    }
    return 0;
}
/*
2 2
DK
HF
3 3
ADC
FJK
IHE
-1 -1

*/