1. 程式人生 > >luogu P1341 無序字母對

luogu P1341 無序字母對

程序 技術 light esp code clu img lap cnblogs

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; }
View Code

luogu P1341 無序字母對