杭電1045 fire net dfs入門

題意是有n*n大小的地圖,地圖上點(.)代表空地,X代表防火牆,在地圖上放置碉堡,碉堡可以橫向或者豎向掃射,所以同一行或列上只能有一個碉堡,但是防火牆可以阻攔攻擊,求最大能放置多少碉堡

// HDOJ1042 fire net
// 思維是主要靠深搜

#include <iostream>
using namespace std;
int visit[5][5];    // visit數組是用來存放狀態的,0代表空地,1代表放了碉堡,2代表防火牆
int mmax, n, cnt;
bool ffind(int x, int y);   // 判斷當前位置是否可以放碉堡
void dfs();

int main()
{
    char str[10];
    while(cin >> n && n)
    {
        for(int i = 1; i <= n; i++)
        {
            cin >> str;
            for(int j = 0; j < n; j++)
                visit[i][j + 1] = (str[j] == 'X' ? 2 : 0);
        }
        cnt = mmax = 0;
        dfs();
        cout << mmax << endl;
    }

    return 0;
}

bool ffind(int x, int y)
{
    // 從(x, y)點開始上下左右判斷,如果遇到碉堡就返回false,如果遇到牆就結束本次循環
    for(int i = y; i >= 1; i--)
    {
        if(visit[x][i] == 1)
            return false;
        if(visit[x][i] == 2)
            break;
    }
    for(int i = y; i <= n; i++)
    {
        if(visit[x][i] == 1)
            return false;
        if(visit[x][i] == 2)
            break;
    }
    for(int i = x; i >= 1; i--)
    {
        if(visit[i][y] == 1)
            return false;
        if(visit[i][y] == 2)
            break;
    }
    for(int i = x; i <= n; i++)
    {
        if(visit[i][y] == 1)
            return false;
        if(visit[i][y] == 2)
            break;
    }

    return true;
}

void dfs()
{
    // 一列一列的深搜,如果發現一點能放碉堡就令狀態數組變爲1,表示放置碉堡
    // 然後繼續往下搜索,放置一個碉堡就領cnt計數器自增
    // 如果搜索完整個,就跳出本次循環,將碉堡重新設置爲空地
    if(cnt > mmax)
        mmax = cnt;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            if(!visit[i][j] && ffind(i,j))
            {
                visit[i][j] = 1;
                cnt++;
                // cout << "in" << endl;    // 測試用
                dfs();
                // cout << "out" << endl;   // 測試用
                visit[i][j] = 0;
                cnt--;
            }
}
發佈了42 篇原創文章 · 獲贊 15 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章