1341 无序字母对

难度:提高+/省选-

题目类型:图论

提交次数:6

涉及知识:dfs/欧拉路径

题目描述

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

输入输出格式

输入格式:

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

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

输出格式:

输出满足要求的字符串。

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

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

输入输出样例

输入样例#1:

4
aZ
tZ
Xt
aX

输出样例#1:

XaZtX

说明

【数据规模与约定】

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

代码:

 1 #include<iostream>
 2 using namespace std;
 3 int n;
 4 const int N = 52;
 5 int map[60][60];
 6 int du[60];
 7 char ans[2500];
 8 bool flag;
 9 int change(char a){
10     int askii = (int)(a);
11     if(askii<97){
12         return askii-65;
13     }
14     else return askii-71;
15 }
16 char rechange(int x){
17     if(x<=25) return char(x+65);
18     else return char(x+71);
19 }
20 void dfs(int x, int step){
21     ans[step] = rechange(x);
22     if(step==n+1){
23         flag = true;
24         return;
25     }
26     for(int i = 0; i < 52; i++){
27         if(map[x][i]>0){
28             map[x][i]--;
29             map[i][x]--;
30             dfs(i,step+1);
31             if(flag) break;
32             map[x][i]++;
33             map[i][x]++;
34         }
35     }
36     if(!flag) ans[step] = 0;
37 }
38 int main(){
39     cin>>n;
40     int i;
41     for(i = 1; i <= n; i++){
42         char a, b;
43         cin>>a>>b;
44         int x = change(a);
45         int y = change(b);
46         map[x][y] = 1;
47         map[y][x] = 1;
48         du[x]++;
49         du[y]++;
50     }
51     int flag = 100;
52     int minn = 100;
53     int odd = 0;
54     for(i = 0; i <= 51; i++){
55         if(du[i]!=0&&minn==100) minn = i;
56         if(du[i]%2 == 1){
57             flag = min(flag, i);
58             odd++;
59         }
60
61     }
62     if(odd!=0&&odd!=2) {
63         cout<<"No Solution"<<endl;
64         return 0;
65     }
66     if(flag!=100) dfs(flag, 1);
67     else dfs(minn,1);
68     for(i = 1; i <= n+1; i++){
69         cout<<ans[i];
70     }
71     cout<<endl;
72     return 0;
73 } 

备注:

欧拉路径就是一笔画,在图中仅有0或2个奇数入度点时存在。昨天下午看了半天求欧拉路径的算法,今天老师嘲讽一通说我看的是假的算法。。dfs+删边就可以了。虽然我很不愿意接受,但这么写写竟然是对的,而且效率还可以。

为什么是对的很简单。从一个奇数入度点出发,如果全是偶数入度点,就从最小的点开始,dfs,走到无路可走时就找到了一个解。注意一定要回溯(否则走入一条死胡同就结束了),肯定不能一到某个点就输出这个点(此时不一定走的就是正确的路),这也是dfs加一个step参量的必要性(最后一次更新一定是正解)(回溯到这个点说明上一次从这个点出去选择的方向走不完图,所以换个方向走)。

字典序很好办。从小到大搜就可以了。

后来codevs过了,洛谷最后一个点过不了。看了一眼讨论,发现ans数组开小了。n的规模可以算,应该是52*52,开成2500就过了。

时间: 2024-08-01 22:54:41

1341 无序字母对的相关文章

洛谷1341 无序字母对

本题地址:http://www.luogu.org/problem/show?pid=1341 题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一个正整数n. 以下n行每行两个字母,表示这两个字母需要相邻. 输出格式: 输出满足要求的字符串. 如果没有满足要求的字符串,请输出“No Solution”. 如果有多种方案,请输出前面的字母的ASCII

Luogu 1341 无序字母对 - 欧拉路径

Solution 找一条字典序最小的欧拉路径. 用 $multiset$ 存储领接表. 欧拉路径模板传送门 Code 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<set> 5 using namespace std; 6 7 const int N = 1e3 + 5; 8 9 int n, up = 'z' - 'A' + 1; 10 int ans[N],

无序字母对

本题地址:http://www.luogu.org/problem/show?pid=1341 题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一个正整数n.以下n行每行两个字母,表示这两个字母需要相邻. 输出格式: 输出满足要求的字符串.如果没有满足要求的字符串,请输出“No Solution”.如果有多种方案,请输出前面的字母的ASCII编码尽

洛谷P1341 无序字母对[无向图欧拉路]

题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一个正整数n. 以下n行每行两个字母,表示这两个字母需要相邻. 输出格式: 输出满足要求的字符串. 如果没有满足要求的字符串,请输出“No Solution”. 如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案 输入输出样例 输入样例#1: 4 aZ tZ Xt aX 输

洛谷P1341 无序字母对(欧拉回路)

P1341 无序字母对 题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一个正整数n. 以下n行每行两个字母,表示这两个字母需要相邻. 输出格式: 输出满足要求的字符串. 如果没有满足要求的字符串,请输出“No Solution”. 如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案 输入输出样例 输入样例#1: 4 a

洛谷P1341 无序字母对

P1341 无序字母对 229通过 806提交 题目提供者yeszy 标签图论福建省历届夏令营 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 不知道哪里错 求解释 题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一个正整数n. 以下n行每行两个字母,表示这两个字母需要相邻. 输出格式: 输出满足要求的字符串. 如果没有满足要求的字符串,

洛谷 P1341 无序字母对 Label:欧拉路 一笔画

题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一个正整数n. 以下n行每行两个字母,表示这两个字母需要相邻. 输出格式: 输出满足要求的字符串. 如果没有满足要求的字符串,请输出“No Solution”. 如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案 输入输出样例 输入样例#1: 4 aZ tZ Xt aX 输

luogu P1341 无序字母对

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数组

p1341 无序字母对

传送门 题目 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入格式: 第一行输入一个正整数n. 以下n行每行两个字母,表示这两个字母需要相邻. 输出格式: 输出满足要求的字符串. 如果没有满足要求的字符串,请输出"No Solution". 如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案 分析 任意俩字母的相邻关系可表示为一条路径,所以在相邻字母间