luogu P1341 无序字母对
P1341 无序字母对
思路:
欧拉回路问题
坑点:
①第三个点出现了
5 ab ac ad ae af
这样的情况
所以我们需要加一点小优化:
for(int i=0; i<=top; i++) { //特判第三个点... if(i==0) continue; if(!tmp[ans[i]][ans[i-1]]) { printf("No Solution"); return 0; } }
②我们还需要保证题目中给出的所有字母均在ans数组中出现,所以需要开2个vis数组,一个记录给出的字母的出现,另外一个纪录ans数组中出现的字母,进行比较。
如果vis数组中出现了,但是vis2数组中并没有出现,那么我们就可以直接输出No Solution,并退出程序即可
上代码:
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const int N = 52; const char e[N] = { 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', 'a','b','c','d','e','f','g', 'h','i','j','k','l','m','n', 'o','p','q','r','s','t', 'u','v','w','x','y','z'}; int n,Max,Min=N,top; int map[N][N],tmp[N][N],ru[N],ans[10000000]; bool vis[N],vis2[N]; void dfs(int u) { for(int v=Min; v<=Max; v++) { if(!vis[v]) continue; if(map[u][v]>0) { map[u][v]--; map[v][u]--; dfs(v); } } ans[top++]=u; } int main() { scanf("%d",&n); char a,b; for(int i=1,u,v; i<=n; i++) { cin>>a>>b; u=a-'A',v=b-'A'; if(u>=32) u-=6; if(v>=32) v-=6; vis[u]=vis[v]=true; map[u][v]++,map[v][u]++; tmp[u][v]++,tmp[v][u]++; ru[u]++,ru[v]++; Max=max(Max,max(u,v)); Min=min(Min,min(u,v)); } int s=Min; for(int i=Min; i<=Max; i++) { if(!vis[i]) continue; if(ru[i]%2==1) { s=i; break; } } dfs(s); top--; for(int i=0; i<=top; i++) { //特判第三个点... vis2[ans[i]]=true; //记录答案中出现的字母 if(i==0) continue; if(!tmp[ans[i]][ans[i-1]]) { printf("No Solution"); return 0; } } for(int i=Min; i<=Max; i++) { if(vis[i] && !vis2[i]) { //当前储存的答案中没有出现应该出现的字母 printf("No Solution"); return 0; } } for(int i=top; i>=0; i--) printf("%c",e[ans[i]]); return 0; }