题目大意:
给出n张多米诺骨牌,每张骨牌都由前后两个0到6的数字组成(1 ≤ N ≤ 100)。要求相邻两张多米诺骨牌接触的一边必须数值相同,给出一种将n张骨牌依次摆放的方法。
这道题开始时想错了,把每一张骨牌当作一个点来做的。。。后来写着写着发现不行了。。。
正解:把每一个数值当作一个节点,每一块骨牌当作一条边(要记录一下正反边),然后再走一遍欧拉路径就可以了,基本上就是水题。。。直接上代码:
/*
ID: Sunshine_cfbsl
LANG: C++
*/
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 105;
typedef pair<int, int> P;
int n, k, deg[7], ans[MAXN], Begin[7], Next[MAXN * 2], to[MAXN * 2], e, vis[MAXN];
void dfs(int u) {
int i;
for(i = Begin[u]; i; i = Next[i]) {
if(vis[(i + 1) >> 1]) continue;
vis[(i + 1) >> 1] = true;
int v = to[i];
dfs(v);
if(i & 1) ans[++k] = (i + 1) >> 1;
else ans[++k] = -(i >> 1);
}
}
void add(int a, int b) {
to[++e] = b;
Next[e] = Begin[a];
Begin[a] = e;
}
int main() {
int i;
scanf("%d", &n);
k = -1;
for(i = 1; i <= n; i++) {
int a, b;
scanf("%d%d", &a, &b);
add(a, b);
add(b, a);
deg[a]++;
deg[b]++;
}
int flag = 0, fp = to[1];
for(i = 0; i < 7; i++)
if(deg[i] & 1) {
flag++;
fp = i;
}
if(flag != 0 && flag != 2) {
printf("No solution\n");
return 0;
}
dfs(fp);
for(i = 1; i <= n; i++)
if(!vis[i]) {
printf("No solution\n");
return 0;
}
for(i = k; i >= 0; i--) {
if(ans[i] < 0) printf("%d -\n", -ans[i]);
else printf("%d +\n", ans[i]);
}
return 0;
}