磁砖样式 另一种思路的dfs

基本的dfs搜索一般都是直接从一个点出发,再从这个点到下一个
但是这题使用了另一种思路的dfs
每次选择点不是根据上一个点来推进,而是从整个地图中选择没有选过的点
也就是扫描一遍地图,从中选择还没有使用过的点,这种方式往往用于两个点之间的转移规则比较复杂的情况,比如这题,每次需要使用两个点,而不是一个,同时有横竖两种方向。
使用这种方式时需要注意在找到第一个点之后需要立即return。

#include <bits/stdc++.h>
#include <hash_map>
#include <hash_set>
using namespace std;

using namespace __gnu_cxx;

//#pragma GCC optimize(2)
#define n 3
#define m 10

int Map[3][10];

bool check(void)
{
    for(int i = 0; i < n-1; i++)
    {
        for(int j = 0; j < m-1; j++)
        {
            int cc = Map[i][j];
            if(Map[i+1][j] == cc && cc == Map[i][j+1] && cc == Map[i+1][j+1])
                return false;
        }
    }

    return true;
}


set<string> ans;

string tmp;

void dfs(int count)
{
    if(count == n*m)
    {
        tmp.clear();

        char ch[3*10];
        int t = 0;

        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                ch[t++]= (Map[i][j]+'A');
            }
        }

        tmp += ch;

        if(check() && ! ans.count(tmp))
        {
            ans.insert(tmp);
          //  cout << tmp << endl;
        }

        return;
    }

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(Map[i][j] == 0)
            {
                if(j+1 < m && Map[i][j+1] == 0)
                {
                    Map[i][j] = 1;
                    Map[i][j+1] = 1;
                    dfs(count + 2);
                    Map[i][j] = 0;
                    Map[i][j+1] = 0;
                }

                if(j+1 < m && Map[i][j+1] == 0)
                {
                    Map[i][j] = 2;
                    Map[i][j+1] = 2;
                    dfs(count + 2);
                    Map[i][j] = 0;
                    Map[i][j+1] = 0;
                }

                if(i+1 < n && Map[i+1][j] == 0)
                {
                    Map[i][j] = 1;
                    Map[i+1][j] = 1;
                    dfs(count+2);
                    Map[i][j] = 0;
                    Map[i+1][j] = 0;
                }
                if(i+1 < n && Map[i+1][j] == 0)
                {
                    Map[i][j] = 2;
                    Map[i+1][j] = 2;
                    dfs(count+2);
                    Map[i][j] = 0;
                    Map[i+1][j] = 0;
                }

                return ;                            // 注意,一定要加上,避免重复计算
            }
        }
    }
}


#define zpl

int main(int argc, char *argv[])
{

    #ifdef zpl
    freopen("F:\\data.txt", "r", stdin);
    #endif // zpl

    dfs(0);

    cout << ans.size() << endl;

    return 0;
}



猜你喜欢

转载自blog.csdn.net/canhelove/article/details/90024654