算法问题实战策略 BOARDCOVER

Posted itdef

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法问题实战策略 BOARDCOVER相关的知识,希望对你有一定的参考价值。

地址 https://algospot.com/judge/problem/read/BOARDCOVER

技术图片技术图片

解法 

DFS 最近似乎在简单DFS上花费太多时间了

首先扫描地图 统计可覆盖的元素个数 如果不是3的倍数 那肯定不能覆盖完全 返回0 

然后进行DFS 尝试各种覆盖办法 一共12种(由于必须覆盖完所有元素 就规定从左上角开始覆盖,其实可以只有四种覆盖办法)

技术图片

 

每次DFS结束则覆盖方法增加1种  尝试所有覆盖方式后 函数也返回

注意需要寻找每次下一个尝试的覆盖点 规定从左上角开始找起 

代码

// 11111111111111.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//




#include <iostream>
#include <vector>



using namespace std;

const int N = 30;

char gmap[N][N];

int loop;
int ans = 0;
int n, m;

struct board {
    int x1, y1;
    int x2, y2;
    int x3, y3;
};

vector<struct board> fillBoad=
{
    {0,0, -1,0, 0,-1},
    {0,0, 1,0,  0,-1},
    {0,0, -1,0, 0,1},
    {0,0, 1,0,  0,1},

    {0,0, 1,0,  1,-1},
    {0,0, -1,0, -1,-1},
    {0,0, 1,0,  1,1},
    {0,0, -1,0, -1,1},

    {0,0, 0,1,  -1,1},
    {0,0, 0,1,  1,1},
    {0,0, 0,-1, 1,-1},
    {0,0, 0,-1, -1-1},
};


bool CheckXY(int x1, int y1, int x2, int y2, int x3, int y3)
{
    if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0 || x3 < 0 || y3 < 0)
        return false;

    if (x1 >= n || x2 >= n || x3 >= n || y1 >= m || y2 >= m || y3 >= m)
        return false;

    if (gmap[x1][y1] == # || gmap[x2][y2] == # || gmap[x3][y3] == #)
        return false;


    return true;
}

void DFS(int x, int y,int needfill)
{
    if (needfill == 0) {
        ans++;
        return;
    }

    for (; x < n; x++) {
        for ( y = 0; y < m; y++) {
            if (gmap[x][y] == .)
                goto FIND;
        }
    }
    FIND:


    for (int i = 0; i < 12; i++) {


        int newx1 = x + fillBoad[i].x1;  
        int newy1 = y + fillBoad[i].y1;
        int newx2 = x + fillBoad[i].x2;
        int newy2 = y + fillBoad[i].y2; 
        int newx3 = x + fillBoad[i].x3; 
        int newy3 = y + fillBoad[i].y3;

        if (CheckXY(newx1, newy1, newx2, newy2, newx3,newy3)) {
            gmap[newx1][newy1] = #;
            gmap[newx2][newy2] = #;
            gmap[newx3][newy3] = #;
            needfill -= 3; 
            
            int p = x; int q = y;
            for (; p < n; p++) {
                for ( q = 0; q < m; q++) {
                    if (gmap[p][q] == .)
                        goto FIND1;
                }
            }

            FIND1:

            DFS( p,q, needfill);

            needfill += 3; 
            gmap[newx1][newy1] = .;
            gmap[newx2][newy2] = .;
            gmap[newx3][newy3] = .;

        }
    }


    return;
}

int main()
{
    cin >> loop;

    while (loop--)
    {
        cin >> n >> m;

        memset(gmap,0,N*N);
        ans = 0;

        int count = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cin >> gmap[i][j];
                if (gmap[i][j] == .)
                    count++;
            }
        }

        if (count % 3 != 0){
            cout << 0 << endl;
            continue;
        }

        DFS(0,0,count);
        cout << ans << endl;
    }

    return 0;
}

ac

技术图片

 

以上是关于算法问题实战策略 BOARDCOVER的主要内容,如果未能解决你的问题,请参考以下文章

算法问题实战策略 QUADTREE

算法问题实战策略 MEETINGROOm

算法问题实战策略 DICTIONARY

《算法问题实战策略》 BOGGLE

算法问题实战策略 FENCE

《算法问题实战策略》-chaper13-数值分析