紫书搜索 习题7-3 UVA

来源:互联网 发布:c语言if并列多个条件 编辑:程序博客网 时间:2021/03/08 01:30

题目链接:

https://vjudge.net/problem/UVA-211

题意:

给一副图,代表多米诺骨牌摆放方式,每两个连成一块牌,如0 0 对应1号排 0 1 对应2号排,问图可以代表几种摆放方式。

题解:

dfs,每个位置的牌不是竖就是横,枚举2个方向,最多枚举28块,O(2^28),加个剪枝,如果进入枚举下一行了,当前行还有没填上的,就直接回溯。

代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;#define MS(a) memset(a,0,sizeof(a))#define MP make_pair#define PB push_backconst int INF = 0x3f3f3f3f;const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;inline ll read(){    ll x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}//////////////////////////////////////////////////////////////////////////const int maxn = 1e5+10;int num[8][9],g[8][9];int res[10][10],vis[10][10],v[30];int dir[2][2] = {{1,0},{0,1}};int ans;void table(){    int cnt = 1;    for(int i=0; i<7; i++)        for(int j=i; j<7; j++)            num[i][j] = num[j][i] = cnt++;}bool ok(int x){    for(int i=0; i<8; i++)        if(vis[x][i] == 0) return false;    return true;}void dfs(int x,int y,int nu){    if(nu == 28){        ans++;        for(int i=0; i<7; i++){            for(int j=0; j<8; j++)                printf("%4d",res[i][j]);            puts("");        }        puts("");        return ;    }    if(x==7) return ;    if(y==8){        if(!ok(x)) return ;  // 这一行没有都被覆盖,这种解不行,回溯        dfs(x+1,0,nu);        return ;    }    if(vis[x][y]){        dfs(x,y+1,nu);        return ;    }    for(int i=0; i<2; i++){        if(i==0 && x==6) continue;        if(i==1 && y==7) continue;        int tx=x+dir[i][0], ty=y+dir[i][1];        int k = num[g[x][y]][g[tx][ty]];        if(vis[tx][ty]) continue;        if(v[k]) continue;        res[x][y] = res[tx][ty] = k;        vis[x][y] = vis[tx][ty] = v[k] = 1;        dfs(x,y+1,nu+1);        vis[x][y] = vis[tx][ty] = v[k] = 0;    }}int main(){    table();    int cas=0;    while(~scanf("%d",&g[0][0])){        MS(vis); MS(v); ans=0;        if(cas) printf("\n\n\n");        for(int i=0; i<7; i++)            for(int j=0; j<8; j++){                if(i==0 && j==0) continue;                scanf("%d",&g[i][j]);            }        printf("Layout #%d:\n\n",++cas);        for(int i=0; i<7; i++){            for(int j=0; j<8; j++)                printf("%4d",g[i][j]);            puts("");        }        puts("");        printf("Maps resulting from layout #%d are:\n\n",cas);        dfs(0,0,0);        printf("There are %d solution(s) for layout #%d.\n",ans,cas);    }    return 0;}
0 0
原创粉丝点击