洛谷1341 无序字母对

题目描述

给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。

输入输出格式

输入格式

第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。

输出格式

输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案

思路

显然,这是一道典型的欧拉回路,每读入两个字母就给这两个字母连一条无向边,跑一边欧拉回路就行了。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=300+5; 
int G[maxn][maxn]; 
int deg[maxn]; 
char tmp[maxn]; 
char ch[maxn*maxn];
int n;
void dfs(int i){ 
    for(int j=0;j<maxn;j++) {
        if(G[i][j]){
            G[i][j]=G[j][i]=0; //表示这条路走过了
            dfs(j);//往下DFS
        }
    }
    ch[n--]=i;//记录欧拉回路的顺序,在这里,我们是倒着记的,所以最后可以直接输出
}
int main() {
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%s",tmp);
        G[tmp[0]][tmp[1]]=G[tmp[1]][tmp[0]]=1;//输入,存边
        deg[tmp[0]]++;
        deg[tmp[1]]++;//记录度数
    }
    char first=0,cnt=0;
    for(int i=0;i<maxn;i++) {
        if(deg[i]%2==1){//从度数为奇数的开始搜
            cnt++;//记录有多少个这样的点
            if(!first)first=i;//记录第一个点
        }
    }
    if(!first){
        for(int i=0;i<maxn;i++)
            if(deg[i]){
                first=i;
                break;
            }
    }
    if(cnt && cnt!=2){
        puts("No Solution");
        return 0;
    }//如果度数为奇数的点不是2的话,就无解
    dfs(first);//搜索
    puts(ch);//直接输出
    return 0;//大功告成
}

猜你喜欢

转载自www.cnblogs.com/xzj213/p/10624132.html