zoukankan      html  css  js  c++  java
  • 洛谷P1127-词链

    Problem 洛谷P1127-词链

    Accept: 256    Submit: 1.3k
    Time Limit: 1000 mSec    Memory Limit : 128MB

    Problem Description

    如果单词 XXX 的末字母与单词 YYY 的首字母相同,则 XXX 与 YYY 可以相连成 X.YX.YX.Y 。(注意: XXX 、 YYY 之间是英文的句号“.”)。例如,单词dog与单词gopher,则doggopher可以相连成dog.gopher

    另外还有一些例子:

    dog.gopher

    gopher.rat

    rat.tiger

    aloha.aloha

    arachnid.dog

    连接成的词可以与其他单词相连,组成更长的词链,例如:

    aloha.arachnid.dog.gopher.rat.tiger

    注意到,“.”两边的字母一定是相同的。

    现在给你一些单词,请你找到字典序最小的词链,使得这些单词在词链中出现且仅出现一次。

     Input

    第一行是一个正整数 n(1≤n≤1000),代表单词数量。

    接下来共有 n行,每行是一个由 120 个小写字母组成的单词

     Output

     只有一行,表示组成字典序最小的词链,若不存在则只输出三个星号“ ∗∗∗”

     

     Sample Input

    6
    aloha
    arachnid
    dog
    gopher
    rat
    tiger

     Sample Output

    aloha.arachnid.dog.gopher.rat.tiger
     
    题目链接:https://www.luogu.org/problemnew/show/P1127
     
    这个题做的很差,感觉很简单,可能还是学艺不精。
     
    剪枝的方式还是值得一提的,这个题乍一看上去没有剪枝的思路,当把整个链和欧拉路径联系起来思路自然就出来了。
    统计每个字符串首尾字母出现次数,在首位出现就++,在末位就--,如果能够连成词链,那么每个字母的统计值只能位0或1,并且如果有1只能是同时有两个,
    据此可以作为充要条件判断是否有解。与此同时,一个剪枝的方式也就出来了,如果是一个+1,一个-1的情况,那么+1的那个必定时开头,避免了很多无用的搜索。
    字典序的问题还是非常简单的,先按字典序sort一下,链式前向星存图,因此加边的时候倒着来就好,遇到词链就输出,退出程序。
     
    还有一个神奇的地方,就是abc和abcb的情况,虽然abc < abcb,但是如果有一个c、b 接上去就成了abcc...、abcbb...
    好像用上述算法还是有问题的,原来还听老师讲过一个类似的题,也是这种情况下有点问题,不过都能AC...
     
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <string>
      6 #include <stack>
      7 #include <algorithm>
      8 using namespace std;
      9 
     10 const int maxn = 1000+10;
     11 const int maxm = maxn*maxn;
     12 
     13 int n,tot,head[maxn];
     14 int len[maxn];
     15 bool vis[maxn];
     16 string str[maxn];
     17 
     18 struct Edge{
     19     int to,next;
     20     Edge(int to = 0,int next = 0) : to(to),next(next) {}
     21 }edge[maxm<<1];
     22 
     23 void AddEdge(int u,int v){
     24     edge[tot].to = v;
     25     edge[tot].next = head[u];
     26     head[u] = tot++;
     27 }
     28 
     29 int top,sta[maxn<<1];
     30 
     31 void output(){
     32     cout << str[sta[1]];
     33     for(int i = 2;i <= n;i++){
     34         printf(".");
     35         cout << str[sta[i]];
     36     }
     37     cout << endl;
     38     exit(0);
     39 }
     40 
     41 void dfs(int u){
     42     vis[u] = true;
     43     sta[++top] = u;
     44     for(int i = head[u];i != -1;i = edge[i].next){
     45         int v = edge[i].to;
     46         if(!vis[v]) dfs(v);
     47     }
     48     if(top == n) output();
     49     vis[u] = false;
     50     top--;
     51 }
     52 
     53 const int kind = 26;
     54 int con[maxn];
     55 
     56 int main()
     57 {
     58     //freopen("input.txt","r",stdin);
     59     cin >> n;
     60     for(int i = 1;i <= n;i++){
     61         cin >> str[i];
     62     }
     63     sort(str+1,str+1+n);
     64     top = 0;
     65     memset(head,-1,sizeof(head));
     66     memset(vis,false,sizeof(vis));
     67     memset(con,0,sizeof(con));
     68     for(int i = 1;i <= n;i++){
     69         len[i] = str[i].size();
     70     }
     71     for(int i = 1;i <= n;i++){
     72         for(int j = n;j >= 1;j--){
     73             if(i!=j && str[i][len[i]-1] == str[j][0]){
     74                 AddEdge(i,j);
     75             }
     76         }
     77     }
     78     for(int i = 1;i <= n;i++){
     79         con[str[i][0]-'a']++;
     80         con[str[i][len[i]-1]-'a']--;
     81     }
     82     int head = -1,cnt = 0,_cnt = 0;
     83     for(int i = 0;i < kind;i++){
     84         if(con[i] == 1){
     85             head = i;
     86             cnt++;
     87         }
     88         else if(con[i] == -1){
     89             _cnt++;
     90         }
     91      }
     92      if(cnt==0 && _cnt==0){
     93         for(int i = 1;i <= n;i++){
     94             dfs(i);
     95         }
     96      }
     97      else if(cnt==1 && _cnt==1){
     98         for(int i = 1;i <= n;i++){
     99             if(str[i][0]-'a' == head) dfs(i);
    100         }
    101      }
    102      printf("***
    ");
    103     return 0;
    104 }
     
  • 相关阅读:
    独立使用 ecj
    公司没有 DBA,Mysql 运维自己来
    mysql安装
    常用模块
    基本数据类型
    Incorrect column name 问题解决
    mysql中date和datetime的区别
    python yield用法详解(未完成)
    mysql报错--initialize specified but the data directory has files in it. Aborting.
    python 列表解析式
  • 原文地址:https://www.cnblogs.com/npugen/p/9495296.html
Copyright © 2011-2022 走看看