• UVA 10441


    UVA 10441 - Catenyms

    题目链接

    题意:给定一些单词,求拼接起来,字典序最小的,注意这里的字典序为一个个单词比过去,并非一个个字母

    思路:欧拉回路。利用并查集判联通,然后欧拉道路判定,最后dfs输出路径

    代码:

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int N = 30;
    
    vector<string> g[N];
    vector<string> ans;
    
    int t, n, parent[N];
    bool used[N][1005];
    
    int find(int x) {
    	return parent[x] == x ? x : parent[x] = find(parent[x]);
    }
    
    int vis[N];
    int cnt, tot, ru[N], chu[N];
    
    void init() { 
    	memset(ru, 0, sizeof(ru));
    	memset(chu, 0, sizeof(chu));
    	memset(vis, 0, sizeof(vis));
    	memset(used, 0, sizeof(used));
    	for (int i = 0; i < 26; i++) {
    		g[i].clear();
    		parent[i] = i;
    	}
    	cnt = 1; tot = 0;
    	scanf("%d", &n);
    	string s;
    	while (n--) {
    		cin >> s;
    		int u = s[0] - 'a', v = s[s.length() - 1] - 'a';
    		if (!vis[u]) {vis[u] = 1; tot++;}
    		if (!vis[v]) {vis[v] = 1; tot++;}
    		ru[v]++; chu[u]++;
    		g[u].push_back(s);
    		int pu = find(u);
    		int pv = find(v);
    		if (pu != pv) {
    			parent[pu] = pv;
    			cnt++;
    		}
    	}
    	for (int i = 0; i < 26; i++)
    		sort(g[i].begin(), g[i].end());
    }
    
    void dfs(int u) {
    	for (int i = 0; i < g[u].size(); i++) {
    		int v = g[u][i][g[u][i].length() - 1] - 'a';
    		if (used[u][i]) continue;
    		used[u][i] = 1;
    		dfs(v);
    		ans.push_back(g[u][i]);
    	}
    }
    
    bool solve() {
    	if (cnt != tot) return false;
    	int Min = 30;
    	int odd = 0, st;
    	for (int i = 0; i < 26; i++) {
    		if (g[i].size()) Min = min(Min, i);
    		if (ru[i] - chu[i] == -1) {
    			odd++;
    			st = i;
    		}
    		else if (chu[i] - ru[i] == -1)
    			odd++;
    		else if (chu[i] != ru[i]) return false;
    		if (odd > 2) return false;
    	}
    	ans.clear();
    	if (!odd) dfs(Min);
    	else dfs(st);
    	for (int i = ans.size() - 1; i > 0; i--)
    		cout << ans[i] << ".";
    	cout << ans[0] << endl;
    	return true;
    }
    
    int main() {
    	scanf("%d", &t);
    	while (t--) {
    		init();
    		if (!solve()) printf("***
    ");
    	}
    	return 0;
    }


  • 相关阅读:
    Jmeter属性和变量
    用trie树解决最大异或对问题(On)
    trie树
    kmp算法
    数学归纳法
    单调栈和单调队列
    区间合并
    离散化
    位运算
    双指针算法
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7290761.html
Copyright © 2020-2023  润新知