zoukankan      html  css  js  c++  java
  • 【洛谷1341】无序字母对(欧拉回路)

    点此看题面

    大致题意:给你(n)各不相同的无序字母对(注意:两个字母可能相同,被这个坑了好几次),请构造一个长度为(n+1)的字符串包含每个字母对。

    欧拉回路

    这是一道裸的欧拉回路,只不过是字符串版的,步骤较经典版略显麻烦。

    依照欧拉回路的思路,我们先统计出每个字母出现的次数。然后对其中奇点的个数分类讨论:

    没有奇点:则可以从任意一个点开始遍历。由于题目中要求字典序最小,所以从字典序最小的点开始遍历。

    有两个奇点:则可以从任意一个奇点开始遍历。由于题目中要求字典序最小,所以从字典序较小的奇点开始遍历。

    以上两种情况皆不满足:说明无解,输出“No Solution”。

    代码

    #include<bits/stdc++.h>
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define LL long long
    #define swap(x,y) (x^=y,y^=x,x^=y)
    #define N ('z'-'A'+1)
    using namespace std;
    int n,ee=0,cnt=0,In[N+5],f[N+5][N+5],ans[100000];
    inline void write(int x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    inline void dfs(int x)//dfs跑一遍欧拉回路
    {
        for(register int i=1;i+'A'-1<='z';++i)
            if(f[x][i]) f[x][i]=f[i][x]=0,dfs(i);//将每一个能到达的字母按字典序一一遍历,并将连接当前字母与要到达的字母间的边删去
        ans[++cnt]=x;//统计答案
    }
    int main()
    {
        register int i,j;char x,y,Min=0;
        for(scanf("%d",&n),i=1;i<=n;++i) cin>>x>>y,f[x-'A'+1][y-'A'+1]=f[y-'A'+1][x-'A'+1]=1,++In[x-'A'+1],++In[y-'A'+1],Min=Min?min(Min,min(x,y)):min(x,y);//更新每个字母的入度,并记录字典序最小的字母,为没有奇点的情况做准备
        int flag=0,t=0;//flag记录奇点的个数,t记录较小的奇点
        for(i=1;i<=N;++i) if(In[i]&1) ++flag,t=t?min(t,i):i;//更新较小的奇点
        if(flag&&flag^2) return puts("No Solution"),0;//如果奇点的个数不为0且不为2,就输出"No Solution"
        for(dfs(flag?t:(Min-'A'+1)),i=cnt;i>0;--i) putchar(ans[i]+'A'-1);//尽量从字典序小的点跑一遍欧拉回路,并倒着输出答案
        return 0;
    }
    
  • 相关阅读:
    Thinkd Pad打开无线网络方法
    模式问题
    SQL数据库,使用事务执行增删改操作,给自己一个后悔的机会
    iOS开发-数据库FMDB队列
    iOS开发-数据库FMDB简单介绍
    iOS开发-地图定位 CoreLocation地理编码
    iOS开发-网络篇 文件的上传
    iOS开发-项目新特性
    iOS开发-Xcode插件管理工具Alcatraz的安装和使用
    iOS开发-AFNetworking 怎样上传数据? 怎样上传模拟表单
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu1341.html
Copyright © 2011-2022 走看看