小码匠的信息学江湖【第84式】:欧拉回路之无序字母对

2023-09-06 14:22:44 浏览数 (1)

对话

老码农总是喜欢揪住细节不放,这道题也是两次才AC,所以本蒟蒻只能乖乖的把原因写清楚。

题目描述

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

输入格式

第一行输入一个正整数 n。

第二行到第 (n 1) 行每行两个字母,表示这两个字母需要相邻。

输出格式

输出满足要求的字符串。

如果没有满足要求的字符串,请输出 No Solution

如果有多种方案,请输出字典序最小的方案(即满足前面的字母的 ASCII 编码尽可能小)。

输入输出样例

输入 #1复制

代码语言:javascript复制
4
aZ
tZ
Xt
aX

输出 #1复制

代码语言:javascript复制
XaZtX
 
说明/提示

不同的无序字母对个数有限,n 的规模可以通过计算得到。

题目

题目原文请移步下面的链接

  • https://www.luogu.com.cn/problem/P1341
    • 参考题解:https://www.luogu.com.cn/problem/P1341
  • 标签:OI图论欧拉回路

正解

  • 先放一个oi_wiki的链接 —>欧拉图相关基础知识
  • 这道题是一个非常明显的欧拉路的题,直接套模版就行,字母为止可以交换,所以是无向图要双向建边
  • 因为都是字符,所以存的时候要转换成int类型,我自己写了函数转的比较小,大家嫌麻烦可以干脆把数组开大一点,毕竟最大的‘z'才到122。小贴士:大写字母和小写字母的ascll码是不紧挨着的,如果要要把字符按照从1开始算的话要小心,当然你直接不管中间的七八个字符也行
  • 最后提一句吧,千万记得欧拉回路的起点是谁都行,找最小就ok,但起点终点不相同的欧拉路的起点是2选1,这个点必须是奇数点本蒟蒻因为这个原因第一次只拿了30分
30分
代码语言:javascript复制
// Copyright (C) 2021-2028 coder-oldgeek.com All rights reserved.
// 题目: 无序字母对
// 链接: https://www.luogu.com.cn/problem/P1341
// 难度: 普及 /提高
// 提交:
// 题解:
// - https://www.luogu.com.cn/problem/solution/P1341
#include <bits/stdc  .h>

using namespace std;

#define endl 'n';


int pan(char x) {
    if (x <= 'z' && x >= 'a') {
        return x - 'a'   27;
    } else {
        return x - 'A'   1;
    }
}

char unpan(int x) {
    if (x <= 52 && x >= 27) {
        char y = x   'a' - 27;
        return y;
    } else {
        char y = x   'A' - 1;
        return y;
    }
}

struct node {
    int to, is;
};

int degree[55];

stack<int> st;
vector<vector<bool>> g(55, vector<bool>(55));

void dfs(int now) {
    for (int i = 1; i < 55;   i) {
        if(!g[now][i]) {
            continue;
        }
        g[now][i] = false;
        g[i][now] = false;
        dfs(i);
    }
    st.push(now);
}

void best_coder() {
    int n;
    cin >> n;
    int k = 0x7f7f7f;
    for (int i = 1; i <= n;   i) {
        string s;
        cin >> s;
        g[pan(s[0])][pan(s[1])] = true;
        g[pan(s[1])][pan(s[0])] = true;
          degree[pan(s[0])];
          degree[pan(s[1])];
        k = min(k, pan(s[1]));
        k = min(k, pan(s[0]));
    }

    int cnt = 0;

    for (int i = 1; i <= 55;   i) {
        if(degree[i] % 2 == 1) {
              cnt;
        }
    }
    if (cnt == 1 || cnt > 2) {
        cout << "No Solution";
        return;
    }

    dfs(k);
    while (!st.empty()) {
        cout << unpan(st.top());
        st.pop();
    }
}

void happy_coder() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

int main() {
    // 小码匠
    best_coder();

    // 最优解
    // happy_coder();

    // 返回
    return 0;
}
AC代码
代码语言:javascript复制
// Copyright (C) 2021-2028 coder-oldgeek.com All rights reserved.
// 题目: 无序字母对
// 链接: https://www.luogu.com.cn/problem/P1341
// 难度: 普及 /提高
// 提交:
// 题解:
// - https://www.luogu.com.cn/problem/solution/P1341
#include <bits/stdc  .h>

using namespace std;

#define endl 'n';


int pan(char x) {
    if (x <= 'z' && x >= 'a') {
        return x - 'a'   27;
    } else {
        return x - 'A'   1;
    }
}

char unpan(int x) {
    if (x <= 52 && x >= 27) {
        char y = x   'a' - 27;
        return y;
    } else {
        char y = x   'A' - 1;
        return y;
    }
}

struct node {
    int to, is;
};

int degree[55];

stack<int> st;
vector<vector<bool>> g(55, vector<bool>(55));

void dfs(int now) {
    for (int i = 1; i < 55;   i) {
        if (!g[now][i]) {
            continue;
        }
        g[now][i] = false;
        g[i][now] = false;
        dfs(i);
    }
    st.push(now);
}

void best_coder() {
    int n;
    cin >> n;
    int k = 0x7f7f7f;
    for (int i = 1; i <= n;   i) {
        string s;
        cin >> s;
        g[pan(s[0])][pan(s[1])] = true;
        g[pan(s[1])][pan(s[0])] = true;
          degree[pan(s[0])];
          degree[pan(s[1])];
        k = min(k, pan(s[1]));
        k = min(k, pan(s[0]));
    }

    int cnt = 0;
    int t = 0x7f7f7f7f;
    for (int i = 1; i <= 55 && cnt <= 2;   i) {
        if (degree[i] % 2 == 1) {
              cnt;
            t = min(t, i);
        }
    }
    if (cnt == 1 || cnt > 2) {
        cout << "No Solution";
        return;
    }
    if (cnt == 0) {
        dfs(k);
    } else {
        dfs(t);
    }

    while (!st.empty()) {
        cout << unpan(st.top());
        st.pop();
    }
}

void happy_coder() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

int main() {
    // 小码匠
    best_coder();

    // 最优解
    // happy_coder();

    // 返回
    return 0;
}

0 人点赞