您的位置:首页 > Web前端

UVa 211 - The Domino Effect [DFS剪枝]

2015-02-13 13:49 375 查看
这道题只看书上的中文解释可能有些费力,理解题后还是比较简单的,对每个数字看能否与右边或下边的数字配对组成一张牌,注意加各种剪枝就行。

#include <bits/stdc++.h>
using namespace std;

int kase, solution;
int tab[10][10], res[10][10], vis[30];
int dict[7][7];
const int dir[2][2] = { { 0, 1 }, { 1, 0 } };

void init()
{
++kase;
solution = 0;
memset(tab, 0, sizeof(tab));
memset(res, 0, sizeof(res));
memset(vis, 0, sizeof(vis));
int cnt = 0;
for (int i = 0; i <= 6; ++i) for (int j = i; j <= 6; ++j) dict[i][j] = ++cnt;
}
bool in()
{
for (int i = 1; i <= 7; ++i)
for (int j = 1; j <= 8; ++j)
if(!(cin >> tab[i][j]))
return false;
if(kase>=2) printf("\n\n\n");
printf("Layout #%d:\n\n", kase);
for (int i = 1; i <= 7; ++i){
for (int j = 1; j <= 8; ++j)
printf("%4d", tab[i][j]);
printf("\n");
}
printf("\n");
return true;
}
void out()
{
if(!solution)
printf("Maps resulting from layout #%d are:\n", kase);
++solution;
printf("\n");
for (int i = 1; i <= 7; ++i){
for (int j = 1; j <= 8; ++j)
printf("%4d", res[i][j]);
printf("\n");
}
}
inline int calc(int x, int y)
{
if (x > y) swap(x, y);
return dict[x][y];
}
void DFS(int d, int r0, int c0)
{
if (d == 28) {out(); return;}
if (c0==9) c0 = 1, ++r0;
if (res[r0][c0]){
DFS(d, r0, c0 + 1);
return;
}
for (int i = 0; i < 2; ++i){
int r = r0 + dir[i][0], c = c0 + dir[i][1];
if(r > 7 || c > 8 || res[r][c]) continue;
int val = calc(tab[r0][c0], tab[r][c]);
if (!vis[val]){
vis[val] = 1; res[r][c] = res[r0][c0] = val;
DFS(d + 1, r0, c0 + 1);
vis[val] = 0; res[r][c] = res[r0][c0] = 0;
}
}
}
int main()
{
ios::sync_with_stdio(false);
while (true){
init();
if(!in())
return 0;
DFS(0, 1, 1);
printf("\nThere are %d solution(s) for layout #%d.\n", solution, kase);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: