无序字母对_洛谷1341_欧拉回路

本文介绍了一种算法,用于解决给定一系列必须相邻的无序字母对后,如何构造一个包含这些字母对的最短字符串的问题。该算法通过构建图模型,并寻找欧拉回路来实现。适用于竞赛编程和图论问题。

题目描述


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

输入格式:


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

以下n行每行两个字母,表示这两个字母需要相邻。

输出格式:


输出满足要求的字符串。

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

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

[数据规模与约定]


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

Analysis


给出的每一对字母都是要相邻的,于是连边,那么题目问的就是能否找一条路径经过所有的边,显然欧拉回路
脑子一热想写vector但是gg了
话说char是可以直接当下标用的,开够256个ascii直接转成int

Code


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#define debug puts("-----")
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define drp(i, st, ed) for (int i = st; i >= ed; i -= 1)
#define fill(x, t) memset(x, t, sizeof(x))
#define max(x, y) x>y?x:y
#define min(x, y) x<y?x:y
#define PI (acos(-1.0))
#define EPS (1e-8)
#define INF (1<<30)
#define ll long long
#define db double
#define ld long double
#define N 256
#define E N * 8 + 1
#define L 25
using namespace std;
int rec[N + 1][N + 1], ind[N + 1];
bool flag = false;
vector<char> ans;
inline int read(){
    int x = 0, v = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9'){
        if (ch == '-'){
            v = -1;
        }
        ch = getchar();
    }
    while (ch <= '9' && ch >= '0'){
        x = (x << 1) + (x << 3) + ch - '0';
        ch = getchar();
    }
    return x * v;
}
inline int addEdge(char x, char y){
    rec[x][y] = 1;
    ind[x] += 1;
    return 0;
}
inline int dfs(char now, int n){
    if (flag){
        return 0;
    }
    ans.push_back(now);
    if (ans.size() == n + 1){
        flag = true;
        rep(i, 0, ans.size() - 1){
            printf("%c", ans[i]);
        }
        return 0;
    }
    rep(tar, 1, N){
        if (rec[now][tar]){
            rec[now][tar] = rec[tar][now] = 0;
            dfs(tar, n);
            rec[now][tar] = rec[tar][now] = 1;
        }
    }
    ans.pop_back();
}
int main(void){
    int n = read();
    rep(i, 1, n){
        char s[3];
        scanf("%s", s);
        char x = s[0], y = s[1];
        addEdge(x, y);
        addEdge(y, x);
    }
    int cnt = 0;
    char st = 'z';
    rep(i, 1, 26){
        char now = (char)('a' + i - 1);
        if (ind[(int)(now)] & 1){
            cnt += 1;
            st = min(st, now);
        }
        now = (char)('A' + i - 1);
        if (ind[(int)(now)] & 1){
            cnt += 1;
            st = min(st, now);
        }
    }
    // printf("%d\n", cnt);
    if (cnt && cnt != 2){
        printf("No Solution\n");
    }else{
        if (!cnt){
            rep(i, 1, N){
                if (ind[i]){
                    st = min(st, i);
                }
            }
        }
        dfs(st, n);
        // printf("%c\n", st);
    }
    return 0;
}
### 关于平台上的回文质数问题 #### 使用欧拉筛法求解回文质数的思路 对于回文质数这一类问题,核心在于两个方面:一是如何高效地筛选出质数;二是怎样快速判定一个数是否为回文数。针对第一个需求,采用线性时间复杂度O(n)级别的欧拉筛算法可以显著提高效率[^1]。 具体来说,在构建埃氏筛的基础上改进而来,通过标记最小素因子来避免重复合数被多次处理的情况发生。当遇到一个新的未被访问过的整数值时,则将其加入到已知素数列表之中,并利用这些已经确认的小范围内的全部素因数去更新更大范围内可能存在的新合数状态。 至于第二个条件——验证回文特性,可以通过字符串反转比较的方式轻松完成。即先将待测正整数转换成字符形式,再检查该串与其逆序版本之间是否存在差异即可得出结论。 #### 代码实现 下面给出一段基于上述原理编写的C++程序: ```cpp #include <iostream> #include <vector> using namespace std; bool isPalindrome(int n){ string s=to_string(n); int l=s.length(); for (int i=0;i<l/2;++i) if(s[i]!=s[l-i-1])return false; return true; } const int MAXN = 1e7; // 定义最大检测界限 bitset<MAXN> notPrime; // 布尔数组记录非质数位置 vector<int> primes; // 动态数组存储找到的所有质数 void eulerSieve(){ notPrime[0]=notPrime[1]=true; for(long long i=2;i<=MAXN;i++){ if(!notPrime[i]){ primes.push_back(i); // 将当前索引作为新的质数保存起来 if(isPalindrome(i)) cout<<i<<" "; // 输出符合条件的回文质数 } for(size_t j=0;j<primes.size() && primes[j]*i<=MAXN ;j++){ notPrime[primes[j]*i]=true; if(i%primes[j]==0) break; } } } ``` 此段代码实现了对指定区间内所有满足既是质数又是回文性质的数据项进行查找并打印的功能。其中`isPalindrome()`辅助函数用于检验给定参数n所代表的具体数值是不是具有镜像对称特征;而主体部分则运用了优化后的欧拉筛技术来进行初步过滤工作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值