UVA - 211 The Domino Effect(多米诺效应)(dfs回溯)

题意:根据多米诺骨牌的编号的7*8矩阵,每个点可以和相邻的点组成的骨牌对应一个编号,问能形成多少种由编号组成的图。

分析:dfs,组成的图必须有1~28所有编号。

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 1};
const int dc[] = {1, 0};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const double eps = 1e-8;
const int MAXN = 1000 + 10;
const int MAXT = 500 + 10;
using namespace std;
int a[10][10];
int ans[10][10];
int id[10][10];//多米诺骨牌的编号
int vis[30];
int mark[10][10];//是否访问过该点
int cnt;
void init(){
    int k = 0;
    for(int i = 0; i < 7; ++i){
        for(int j = i; j < 7; ++j){
            id[i][j] = id[j][i] = ++k;
        }
    }
}
bool judge1(int x, int y){
    return x >= 0 && x <= 6 && y >= 0 && y <= 7;
}
bool judge2(int x){
    for(int i = 0; i < 8; ++i){
        if(!mark[x][i]) return true;
    }
    return false;
}
void dfs(int x, int y, int cur){
    if(cur == 28){
        ++cnt;
        for(int i = 0; i < 7; ++i){
            for(int j = 0; j < 8; ++j){
                printf("%4d", ans[i][j]);
            }
            printf("\n");
        }
        printf("\n");
        return;
    }
    if(x == 7) return;
    if(y == 8){
        if(judge2(x)) return;//如果这一行有未访问的
        dfs(x + 1, 0, cur);
        return;
    }
    if(mark[x][y]){
        dfs(x, y + 1, cur);
        return;
    }
    for(int i = 0; i < 2; ++i){//向右或向下
        int tx = x + dr[i];
        int ty = y + dc[i];
        if(judge1(tx, ty) && !mark[tx][ty] && !vis[id[a[x][y]][a[tx][ty]]]){//下标合法、未被访问过,编号未用过
            ans[x][y] = ans[tx][ty] = id[a[x][y]][a[tx][ty]];
            mark[x][y] = mark[tx][ty] = vis[id[a[x][y]][a[tx][ty]]] = 1;
            dfs(x, y + 1, cur + 1);
            mark[x][y] = mark[tx][ty] = vis[id[a[x][y]][a[tx][ty]]] = 0;
        }
    }
}
int main(){
    init();
    int x;
    int kase = 0;
    while(scanf("%d", &x) == 1){
        if(kase) printf("\n\n\n");
        cnt = 0;
        memset(vis, 0, sizeof vis);
        memset(ans, 0, sizeof ans);
        memset(mark, 0, sizeof mark);
        a[0][0] = x;
        for(int i = 0; i < 7; ++i){
            for(int j = 0; j < 8; ++j){
                if(!i && !j) continue;
                scanf("%d", &a[i][j]);
            }
        }
        printf("Layout #%d:\n\n", ++kase);
        for(int i = 0; i < 7; ++i){
            for(int j = 0; j < 8; ++j){
                printf("%4d", a[i][j]);
            }
            printf("\n");
        }
        printf("\nMaps resulting from layout #%d are:\n\n", kase);
        dfs(0, 0, 0);
        printf("There are %d solution(s) for layout #%d.\n", cnt, kase);
    }
    return 0;
}

 

posted @ 2017-01-18 17:49  Somnuspoppy  阅读(283)  评论(0编辑  收藏  举报