zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    POJ3233 构造子矩阵+矩阵快速幂
    HDU4565-数学推导求递推公式+矩阵快速幂
    记录一个状压DP用到的骚操作
    POJ1273 最大流模板
    图论复习...
    2017-7 实训经验贴
    Polya定理应用实例
    直线,椭圆,三角形,折线分割平面问题
    hdu4801 PocketCube 2阶魔方
    1256:献给阿尔吉侬的花束
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/6297646.html
Copyright © 2011-2022 走看看