题意:n个诺米骨牌,每个骨牌的两面都有数字(0 ~ 6),求n个骨牌的一个排列,满足相邻骨牌相邻的一面的数字相同。
题解:每张骨牌当作一条边,啥意思呢?比如说第一张骨牌的两面是3和4,那么就在3和4之间连一条编号为1的无向边,建好图好,判断这张图能不能一笔画完,也就是一条欧拉路径能不能覆盖完所有的边。
PS:注意图可能是不连通,测试点4就是有多个连通块。
#include "stdafx.h" #pragma warning(disable:4996) #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #define ll long long #define P pair<int, int> #define PP pair<int,pair<int, int>> #define pb push_back #define pp pop_back #define lson root << 1 #define INF (int)2e9 + 7 #define rson root << 1 | 1 #define LINF (unsigned long long int)1e18 #define mem(arry, in) memset(arry, in, sizeof(arry)) using namespace std; const int N = 100005; int n, tot; int head[10], use[300], deg[10]; vector<int> ans; struct node { int to, next, id; } e[300]; void Inite() { tot = 0; mem(head, -1), mem(use, 0), mem(deg, 0); } void addedge(int u, int v, int id) { e[tot].to = v; e[tot].id = id; e[tot].next = head[u]; head[u] = tot++; } void DFS(int u) { for (int i = head[u]; i != -1; i = e[i].next) { int v = e[i].to; if (!use[i]) { use[i] = use[i ^ 1] = 1; DFS(v); ans.pb(e[i].id); } } } void Solve() { int cnt = 0, pos = -1; for (int i = 0; i <= 6; i++) if (deg[i] && (deg[i] & 1)) cnt++, pos = i; if (cnt != 0 && cnt != 2) puts("No solution"); else { if (pos == -1) { for (int i = 0; i <= 6; i++) if (deg[i]) pos = i; } DFS(pos); if (ans.size() != n) { puts("No solution"); return; } for(int i = ans.size() - 1; i >= 0; i--) { if (ans[i] > 0) printf("%d + ", ans[i]); else printf("%d - ", -ans[i]); } } ans.clear(); } int main() { while (scanf("%d",&n) != EOF) { Inite(); for (int i = 1; i <= n; i++) { int u, v; scanf("%d %d", &u, &v); addedge(u, v, i); addedge(v, u, -i); deg[u]++; deg[v]++; } Solve(); } return 0; }