1. 程式人生 > 實用技巧 >76掃雷遊戲(529)

76掃雷遊戲(529)

作者: Turbo時間限制: 1S章節: 寬度優先搜尋

晚於: 2020-08-26 12:00:00後提交分數乘係數50%

截止日期: 2020-09-02 12:00:00

問題描述 :

讓我們一起來玩掃雷遊戲!

給定一個代表遊戲板的二維字元矩陣。 'M' 代表一個未挖出的地雷,'E' 代表一個未挖出的空方塊,'B' 代表沒有相鄰(上,下,左,右,和所有4個對角線)地雷的已挖出的空白方塊,數字('1' 到 '8')表示有多少地雷與這塊已挖出的方塊相鄰,'X' 則表示一個已挖出的地雷。

現在給出在所有未挖出的方塊中('M'或者'E')的下一個點選位置(行和列索引),根據以下規則,返回相應位置被點選後對應的面板:

如果一個地雷('M')被挖出,遊戲就結束了- 把它改為 'X'。

如果一個沒有相鄰地雷的空方塊('E')被挖出,修改它為('B'),並且所有和其相鄰的未挖出方塊都應該被遞迴地揭露。

如果一個至少與一個地雷相鄰的空方塊('E')被挖出,修改它為數字('1'到'8'),表示相鄰地雷的數量。

如果在此次點選中,若無更多方塊可被揭露,則返回面板。

示例 1:

輸入:

[['E', 'E', 'E', 'E', 'E'],

['E', 'E', 'M', 'E', 'E'],

['E', 'E', 'E', 'E', 'E'],

['E', 'E', 'E', 'E', 'E']]

Click : [3,0]

輸出:

[['B', '1', 'E', '1', 'B'],

['B', '1', 'M', '1', 'B'],

['B', '1', '1', '1', 'B'],

['B', 'B', 'B', 'B', 'B']]

解釋:

示例 2:

輸入:

[['B', '1', 'E', '1', 'B'],

['B', '1', 'M', '1', 'B'],

['B', '1', '1', '1', 'B'],

['B', 'B', 'B', 'B', 'B']]

Click : [1,2]

輸出:

[['B', '1', 'E', '1', 'B'],

['B', '1', 'X', '1', 'B'],

['B', '1', '1', '1', 'B'],

['B', 'B', 'B', 'B', 'B']]

解釋:

注意:

輸入矩陣的寬和高的範圍為 [1,50]。

點選的位置只能是未被挖出的方塊 ('M' 或者 'E'),這也意味著面板至少包含一個可點選的方塊。

輸入面板不會是遊戲結束的狀態(即有地雷已被挖出)。

簡單起見,未提及的規則在這個問題中可被忽略。例如,當遊戲結束時你不需要挖出所有地雷,考慮所有你可能贏得遊戲或標記方塊的情況。

可使用以下main函式:

int main()

{

vector<vector<char> > board;

int m,n,x,y;

cin>>m;

cin>>n;

char ch;

for(int i=0; i<m; i++)

{

vector<char> aLine;

for(int j=0; j<n; j++)

{

cin>>ch;

aLine.push_back(ch);

}

board.push_back(aLine);

}

cin>>x>>y;

vector<int> click;

click.push_back(x);

click.push_back(y);

vector<vector<char>> res=Solution().updateBoard(board,click);

for(int i=0; i<res.size(); i++)

{

vector<char> aLine = res[i];

for(int j=0; j<aLine.size(); j++)

cout<<aLine[j];

cout<<endl;

}

return 0;

}

輸入說明 :

首先輸入矩陣的高度m和寬度n,它們的範圍為 [1,50]

然後輸入m行,每行n個字元,字元的含義見描述。

最後輸入兩個整數,表示點選的位置行、列座標。

輸出說明 :

輸出最後矩陣的狀態

輸入範例 :

輸出範例 :

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

class Solution {
public:
    const int dx[8]={0,0,1,1,1,-1,-1,-1};
    const int dy[8]={1,-1,-1,0,1,-1,0,1};
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) 
    {
        int x=click[0],y=click[1];
        if(board[x][y]=='M')//如果是M。直接修改成X,返回 
        {
            board[x][y]='X';
            return board;
        }
        queue<pair<int,int>> Q;
        Q.push({x,y});
        board[x][y]='B';//先把值赴成B 
        int m=board.size(),n=board[0].size();
        while(!Q.empty())//寬度搜索 
        {
            pair<int,int> front=Q.front();
            Q.pop();
            int count=0;
            for(int i=0;i<8;i++) 
            {
                int newx=front.first+dx[i];
                int newy=front.second+dy[i];
                if(newx>=0&&newx<m&&newy>=0&&newy<n&&board[newx][newy]=='M')//判斷出佇列的附近有沒有'M',有的話個數加1 
                    count++;
            }
            if(count==0)//如果附近沒有雷,進行寬度有限搜尋八個方向的 
            {
                for(int i=0;i<8;i++) 
                {
                int newx=front.first+dx[i];
                int newy=front.second+dy[i];
                if(newx>=0&&newx<m&&newy>=0&&newy<n&&board[newx][newy]=='E')
                {
                    board[newx][newy]='B';
                    Q.push({newx,newy})    ;
                }
                }
            }
            else//如果附近有雷,把個數改成雷的個數 
                board[front.first][front.second]='0'+count;
        }
        return board;
    }
};
    

int main()
{
    vector<vector<char> > board;
    int m,n,x,y;
    cin>>m;
    cin>>n;

    char ch;
    for(int i=0; i<m; i++)
    {
        vector<char> aLine;
        for(int j=0; j<n; j++)
        {
            cin>>ch;
            aLine.push_back(ch);
        }
        board.push_back(aLine);
    }
    cin>>x>>y;
    vector<int> click;
    click.push_back(x);
    click.push_back(y);
    vector<vector<char>> res=Solution().updateBoard(board,click);
    for(int i=0; i<res.size(); i++)
    {
        vector<char> aLine = res[i];
        for(int j=0; j<aLine.size(); j++)
            cout<<aLine[j];
        cout<<endl;
    }
    return 0;
}