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;
}
posted @ 2012-07-16 22:09  沐阳  阅读(4444)  评论(0编辑  收藏  举报