zoukankan      html  css  js  c++  java
  • bfs(标记整个棋盘)

    1004 四子连棋

     

    时间限制: 1 s
    空间限制: 128000 KB
    题目等级 : 黄金 Gold
     
     
     
    题目描述 Description

    在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。

     
     

     

    输入描述 Input Description
    从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
    输出描述 Output Description

    用最少的步数移动到目标棋局的步数。

    样例输入 Sample Input

    BWBO
    WBWB
    BWBW
    WBWO

    样例输出 Sample Output

    5

    数据范围及提示 Data Size & Hint

    hi

    还有迭代加深搜的方法,有待探索。

    #include<bits/stdc++.h>
    #define rep(i , n) for(int i = 0 ; i < (n) ; i++)
    using namespace std;
    char m[4][4];
    int dir[4][2] = {{1 , 0},{-1 , 0},{0 , 1},{0, -1}};
    struct node{
        char M[4][4];
        int dis ;
        char last;
        node(char m[4][4] , int d = 0 , char c = 'B')
        {
            rep(i , 4)
            {
                rep(j , 4)
                {
                    M[i][j] = m[i][j];
                }
            }
            dis = d ;//移动步数
            last = c ;//标录上一次与哪个棋子进行了交换
        }
    };
    
    string con(char m[4][4])//比较移动后的棋盘与之前的棋盘是否相同与map<string , int>相结合结合
    {
        string s = "";
        rep(i , 4)
        rep(j , 4)
        s += m[i][j];
        return s;
    }
    
    bool judge(char m[4][4])//判断是否有四子连棋
    {
        rep(i , 4)
        {
            if(m[i][0] == m[i][1] && m[i][1] == m[i][2] && m[i][2] == m[i][3])
                return true ;
            if(m[0][i] == m[1][i] && m[1][i] == m[2][i] && m[2][i] == m[3][i])
                return true ;
        }
        if(m[0][0] == m[1][1] && m[1][1] == m[2][2] && m[2][2] == m[3][3])
            return true ;
        if(m[3][0] == m[2][1] && m[2][1] == m[1][2] && m[1][2] == m[0][3])
            return true ;
        return false ;
    }
    map<string , int>vis;
    
    int main()
    {
        rep(i , 4)
        rep(j , 4)
        cin >> m[i][j];
        queue<node>q;
        q.push(node(m , 0 , 'O'));
        vis[con(m)] = 1 ;
        while(!q.empty())
        {
            node t = q.front() ;
            q.pop() ;
            if(judge(t.M))
            {
                cout << t.dis <<endl ;
                return 0 ;
            }
            int x[2] , y[2];
            int num = -1 ;
            rep(i , 4)
            {
                rep(j , 4)
                {
                    if(t.M[i][j] == 'O')
                    {
                        x[++num] = i;
                        y[num] = j ;
                    }
                }
            }
            rep(i , 2)
            {
                rep(j , 4)
                {
                    int xx = x[i] + dir[j][0];
                    int yy = y[i] + dir[j][1];
                    char temp[4][4];
                    rep(i , 4)
                    rep(j , 4)
                    temp[i][j] = t.M[i][j];
                    if(xx >= 0 && xx < 4 && yy >= 0 && yy < 4 &&t.M[xx][yy]!='O' && t.M[xx][yy] != t.last) //空与空不移,不和上一次移过的一样
                    {
                        temp[x[i]][y[i]] = temp[xx][yy];
                        temp[xx][yy] = 'O';
                    }
                    string s = con(temp);
                    if(!vis[s])//移完过后是否与之前的棋盘相同
                    {
                        vis[s] = 1 ;
                        q.push(node(temp , t.dis+1 , temp[x[i]][y[i]]));
                        if(judge(temp))
                        {
                            cout << t.dis+1 << endl;
                            return 0 ;
                        }
                    }
                }
            }
        }
    
        return 0;
    }
  • 相关阅读:
    利用循环实现评论数据结构
    models中字段用处总结
    models中字段结合admin可以做验证用
    学生成绩信息管理系统
    递归完成多级评论
    python负数求余与整除原则
    python列表推导式
    Python中sorted()和sort()区别
    购物车代码(学习版,很多地方需要优化)
    for.....else用法
  • 原文地址:https://www.cnblogs.com/nonames/p/11256457.html
Copyright © 2011-2022 走看看