题目链接:点击打开链接
题意:给定n个长度为3各不相同的字符串,猜一个n+2位的密码。
这个密码包含上面的所有字符串
思路:
把 abc 拆成ab -> bc
则得到一个图,目标就是走遍所有 ab->bc 这样的边,也就是找一条欧拉通路。
#include <cstdio> #include <algorithm> #include <string.h> #include <queue> #include <cstring> #include <cmath> #include <iostream> #include <vector> using namespace std; typedef pair<int, int> pii; typedef long long ll; vector<pii>G[500000]; int deg[4000]; int ans[500000], top; int v[500000]; int cur[4000]; void eur(int s, int p) { int f; while (cur[s]<G[s].size()) if (v[G[s][f = cur[s]++].second] == 0) { v[G[s][f].second] = 1; eur(G[s][f].first, G[s][f].second); } ans[top++] = p; } char c[200005][5]; int n; int ch(char c){ if ('0' <= c && c <= '9')return c - '0'; if ('a' <= c && c <= 'z')return c - 'a' + 10; return c - 'A' + 36; } int getx(int id){ return ch(c[id][0]) * 62 + ch(c[id][1]); } int gety(int id){ return ch(c[id][1]) * 62 + ch(c[id][2]); } bool ok(){ int x = 0, y = 0, pos = getx(0); for (int i = 0; i < 4000; i++){ if (deg[i]>1 || deg[i] < -1)return false; if (deg[i] == 1) x++, pos = i; if (deg[i] == -1)y++; } if (x != y || x>1)return false; eur(pos, -1); top--; return top >= n; } void input(){ memset(deg, 0, sizeof deg); memset(cur, 0, sizeof cur); memset(v, 0, sizeof v); scanf("%d", &n); for (int i = 0; i < n; i++){ scanf("%s", c[i]); int x = getx(i), y = gety(i); G[x].push_back(pii(y, i)); deg[x]++; deg[y]--; } } int main(){ input(); if (ok()) { puts("YES"); printf("%s", c[ans[top - 1]]); for (int i = top - 2; i>-1; i--) printf("%s", c[ans[i]] + 2); puts(""); } else puts("NO"); return 0; }
时间: 2024-10-11 00:34:17