HUT-XXXX 俄罗斯方块 dfs

首先将7种方块拆成19种方块,然后在进行dfs组合,当然如果给定的N*M不是4的倍数的时候记得直接输出0。

代码如下:

#include <cstdlib>

#include <cstring>

#include <cstdio>

using namespace std;



int N, M, ans, END, G[35][35], many[20];



int mp[20] = {1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7};



char ss[50][6][6] = {

    { "####" }, {"#", "#", "#", "#"}, 

    { "##", "##" }, { "#", "###" }, 

    { "##", "#", "#"}, { "###", "  #" }, 

    { " #", " #", "##" },

    { "  #", "###" }, { "#", "#", "##" },

    { "###", "#" }, { "##", " #", " #" },

    { " #", "###" }, 

    { "#", "##", "#" }, {"###", " #"}, 

    { " #", "##", " #" }, { "##", " ##" },

    { " #", "##", "#" }, { " ##", "##" },

    { "#", "##", " #" }, {"#", "##", " #"}

};



struct Node

{

    char s[6][6];

}e[50];



void pre()

{

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

        memcpy(e[i].s, ss[i], sizeof (ss[0]));

    }

}



bool judge(int x, int y)

{

    if (x < 1 || x > N || y < 1 || y > M) {

        return false;

    }

    else {

        return true;

    }

}



bool Getpos(int &x, int &y)

{

    for (int i = 1; i <= N; ++i) {

        for (int j = 1; j <= M; ++j) {

            if (!G[i][j]) {

                x = i, y = j;

                return true;

            }

        }

    }

    return false;

}



bool OK(int x, int y, int No)

{

    int rec[6][2], cnt = 0, first = 1;

    int _x, _y;

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

        for (int j = 0; j < 6; ++j) {

            if (e[No].s[i][j] == '#') {

                if (first) {

                    _x = i, _y = j;

                    first = 0;

                }

                if (!judge(x+(i-_x), y+(j-_y)) || G[x+(i-_x)][y+(j-_y)] != 0) {

                    return false;

                }

                else {

                    ++cnt;

                    rec[cnt][0] = x + i - _x;

                    rec[cnt][1] = y + j - _y;

                }

            }

        }

    }

    for (int i = 1; i <= cnt; ++i) {

        G[rec[i][0]][rec[i][1]] = 1;

    }

    return true;

}



void erase(int x, int y, int No)

{

    int _x, _y, first = 1;

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

        for (int j = 0; j < 6; ++j) {

            if (e[No].s[i][j] == '#') {

                if (first) {

                    _x = i, _y = j;

                    first = 0;         

                }

                G[x+i-_x][y+j-_y] = 0;

            }

        }

    }

}



void print(int No)

{

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

        for (int j = 0; j < 6; ++j) {

            printf("%c", e[No].s[i][j]);

        }

        puts("");

    }

}



void dfs(int x, int y, int No, int num)

{

    int xx, yy;

    if (!OK(x, y, No)) {

        return;

    }

    --many[mp[No]];

    if (num == END) {

        ++ans;

    }

    else {

        Getpos(xx, yy);

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

            if (many[mp[i]]) {

                dfs(xx, yy, i, num+1);

            }

        }

    }

    erase(x, y, No);

    ++many[mp[No]];

}



int main()

{

    pre();

    int T;

    scanf("%d", &T);

    while (T--) {

        memset(many, 0, sizeof (many));

        ans = 0;

        scanf("%d %d", &N, &M);

        for (int i = 1; i <= 7; ++i) {

            scanf("%d", &many[i]);

        }

        if ((N*M)%4!=0) {

            puts("0");

            continue;

        }

        END = (N*M)/4; 

        for (int k = 0; k < 19; ++k) {

            if (many[mp[k]]) {

                dfs(1, 1, k, 1);

            }

        }

        printf("%d\n", ans);

    }

    return 0;

}

你可能感兴趣的:(DFS)