• [POJ2337]Catenyms


    题目大意:
      定义一个catenym是一对单词,满足第一个单词的末尾字符与第二个单词的开头字符相等。
      定义复合catenym是一些单词,满足第i个单词的末尾字符与第i+1个单词的开头字符相等。
      给你n个字符串,判断它们是否能构成复合catenym。
      如果能,求出字典序最小的那个catenym。

    思路:
      以字母为点,单词为边建图。用类似Fleury算法,跑一边欧拉路径,如果能跑出欧拉路经则说明可以构成。
      为了保证catenym的字典序最小,我们就要保证在Fleury的时候,按照字典序遍历。
      因此我们要先对所有的单词按字典序排序,然后加边。

     1 */
     2 #include<stack>
     3 #include<string>
     4 #include<vector>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<functional>
     8 const int N=1000,V=26;
     9 std::string s[N];
    10 struct Edge {
    11     int to,id;
    12     bool vis;
    13 };
    14 std::vector<Edge> e[V];
    15 inline void add_edge(const int &u,const int &v,const int &i) {
    16     e[u].push_back((Edge){v,i,false});
    17 }
    18 inline int idx(const int &ch) {
    19     return ch-'a';
    20 }
    21 bool vis[V];
    22 int in[V],out[V];
    23 std::stack<int> ans;
    24 void dfs(const int &x) {
    25     for(std::vector<Edge>::reverse_iterator i=e[x].rbegin();i!=e[x].rend();i++) {
    26         if(i->vis) continue;
    27         i->vis=true;
    28         dfs(i->to);
    29         ans.push(i->id);
    30     }
    31 }
    32 inline void init() {
    33     for(register int i=0;i<V;i++) e[i].clear();
    34     std::fill(&in[0],&in[V],0);
    35     std::fill(&out[0],&out[V],0);
    36     std::fill(&vis[0],&vis[V],false);
    37     while(!ans.empty()) ans.pop();
    38 }
    39 int main() {
    40     std::ios_base::sync_with_stdio(false);
    41     std::cin.tie(NULL);
    42     register int T;
    43     for(std::cin>>T;T;T--) {
    44         init();
    45         int n;
    46         std::cin>>n;
    47         for(register int i=0;i<n;i++) {
    48             std::cin>>s[i];
    49         }
    50         std::sort(&s[0],&s[n],std::greater<std::string>());
    51         int start=V;
    52         for(register int i=0;i<n;i++) {
    53             const int &u=idx(*s[i].begin()),&v=idx(*--s[i].end());
    54             out[u]++;
    55             in[v]++;
    56             add_edge(u,v,i);
    57             start=std::min(start,std::min(u,v));
    58         }
    59         int cnts=0,cntt=0;
    60         bool flag=false;
    61         for(register int i=0;i<V;i++) {
    62             if(out[i]-in[i]==1) {
    63                 cnts++;
    64                 start=i;
    65             } else if(in[i]-out[i]==1) {
    66                 cntt++;
    67             } else if(in[i]!=out[i]){
    68                 flag=true;
    69             }
    70         }
    71         if(flag||!((cnts==0&&cntt==0)||(cnts==1&&cntt==1))) {
    72             std::cout<<"***"<<std::endl;
    73             continue;
    74         }
    75         dfs(start);
    76         if((signed)ans.size()!=n) {
    77             std::cout<<"***"<<std::endl;
    78             continue;
    79         }
    80         std::cout<<s[ans.top()];
    81         ans.pop();
    82         while(!ans.empty()) {
    83             std::cout<<'.'<<s[ans.top()];
    84             ans.pop();
    85         }
    86         std::cout<<std::endl;
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    有问题的Py代码
    Python撑爆内存的代码
    python socket 绑定端口收发信息
    python socket UDP通信
    B类IP地址
    python in的用法
    Python continue的用法
    python27接受用户输入的数据
    基于jQuery实现左右图片轮播(原理通用)
    Jquery实现的简单轮播效果-代码
  • 原文地址:https://www.cnblogs.com/skylee03/p/7593919.html
Copyright © 2020-2023  润新知