NYOJ 单词拼接

# include<iostream>
# include<string>
# include<string.h>
# include<queue>
# include<stdio.h>
# include<math.h>
#include <algorithm>
using namespace std;
#define MAX 2005
int first[MAX],next[MAX],u[MAX],v[MAX],used[MAX],h=1,ct=1,in[MAX],ans[MAX];
int out[MAX],x=0;
string s[MAX];
char ch;
void AddEdge(int a,int b)
{
    u[h] = a;
    v[h] = b;
    out[a]++;
    in[b]++;
    next[h] = first[u[h]];
    first[u[h]] = h;
    h++;
}

int judge(int p)
{
    int count1 = 0;
    int count2 = 0;
    int vertex[2];
    for(int i=1;i<=p;i++)
    {
        if(out[i]-in[i] == 1 )
        {
            if(count1>=1)
                return -1;
            vertex[0] = i;
            count1++;
        }
        else if(out[i]-in[i] == -1 )
        {
            if(count2>=1)
                return -1;
            vertex[1] = i;
            count2++;
        }
        else if(out[i]-in[i] == 0)
        {
            continue;
        }
        else            //WA原因
        {
            return -1;
        }
    }
    if(count1==1 && count2==1)
    {
        return vertex[0];
    }
    else if(count1==0 && count2==0)
    {
        for(int i=1;i<=26;i++)
        {
            if(in[i]!=0 && out[i]!=0)
                return i;
        }
    }
    else
        return -1;
}
void dfs(int k)        //k是出发顶点
{
    for(int i = 1; i < h; i++)
    {
        if(u[i] == k)
        {
            //printf("%d %d\n------------\n",u[i],k);
            if(used[i]!=0)
            {
                used[i] = 0;
                dfs(v[i]);
                ans[ct++] = i;
                //printf("%d %d\n------------\n",ct,i);
                ///求出后答案是倒着的
            }
        }
    }

}
int main()
{
    int m,n,i,j;
    cin>>n;
    while(n--)
    {
        cin>>m;
        h = 1;
        x = 0;
        ct = 1;
        for(i=0;i<MAX;i++)
        {
            first[i] = -1;
            next[i] = -1;
            used[i] = 1;
            in[i] = 0;
            out[i] = 0;
        } 

        for(i=1;i<=m;i++)
        {
            cin>>s[i];
        }
        sort(s+1,s+m+1);
        for(i=1;i<=m;i++)
        {
            int a,b;
            a = s[i][0] - ‘a‘ + 1;
            b = s[i][ s[i].length()-1 ] - ‘a‘ + 1;
            //printf("%d %d",a,b);
            AddEdge(a,b);
        }
        int k,flag = 1;
        k = judge(26);
        /*
        printf("%d\n------------------\n",k);

        for(i=1;i<h;i++)
                {
                   printf("%d %d %d\n",u[i],v[i],used[i]);
            }
        printf("\n------------------\n");
        */
        dfs(k);

        if(k==-1)
        {
            flag = 0;
        }
        else
        {
            for(i=1;i<h;i++)
                {
                   if(used[i]!=0)
                   {
                       flag = 0;
                    break;
                }
            }
        }

        if(flag==1)
        {
            for(i=ct-1;i>=1;i--)
            {
                if(i!=1)
                    cout<<s[ans[i]]<<"." ;
                else
                    cout<<s[ans[i]];
            }
            cout<<endl;
        }
        else        printf("***\n");

    }
    return 0;
}

原文地址:https://www.cnblogs.com/fzuhyj/p/9494969.html

时间: 2024-07-31 20:03:42

NYOJ 单词拼接的相关文章

nyoj 单词拼接(并查集判断连通性+欧拉路径)

这题还是比较难的. 首先建图方面,如果单纯的把单词作为点,能拼接的关系作为边,那么就是哈密顿图(每个点仅能走一次),难度比较大. 换一种思路,就是把每个单词看成一条有向边,由该单词的首字母指向尾字母. 那么这题便是欧拉图的问题了. 本质上采用的还是搜索,但是为了快速得到字典序最小的欧拉路径,首先要对单词集进行排序. 排完序后,用边集数组存图:再通过计算各点的出度与入度,同时判断基图(不考虑边的方向的图)的连通性,判断是否存在欧拉回路或欧拉通路. 如果存在欧拉回路,那么就从0开始搜索: 如果存在欧

NYOJ 99单词拼接(有向图的欧拉(回)路)

1 /* 2 NYOJ 99单词拼接: 3 思路:欧拉回路或者欧拉路的搜索! 4 注意:是有向图的!不要当成无向图,否则在在搜索之前的判断中因为判断有无导致不必要的搜索,以致TLE! 5 有向图的欧拉路:abs(In[i] - Out[i])==1(入度[i] - 出度[i])的节点个数为两个 6 有向图的欧拉回路:所有的节点都有In[i]==Out[i] 7 */ 8 #include<iostream> 9 #include<cstring> 10 #include<cs

C语言DFS(7)___单词拼接(NYoj 99)

单词拼接 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串. 前一个单词的结尾应该与下一个单词的道字母相同. 如 aloha dog arachnid gopher tiger rat 可以拼接成:aloha.arachnid.dog.gopher.rat.tiger 输入 第一行是一个整数N(0<N<20),表示测试数据的组数 每组测试数据的第一行是一个整数M,表示该组测试数据中有M(2<M<1000)个互不相同的单词,随后的M行,每行是一个长度不超过30的单词,单词全部

计蒜客 单词拼接

花椰菜君给了蒜头君 n 个单词,如果一个单词的最后一个字母和另一个单词的第一个字母相同,那么两个单词就可以连接在一起组成一个新的单词.现在花椰菜君想要蒜头君计算一下,给定的 n 个单词是否可以全部连接在一起. 输入格式 第一行输入一个整数 n,代表一共有 n 个单词(1≤n≤100,000). 接下来输入 nn行,每行输入一个单词.单词均由小写字母组成,每个单词长度不超过 20. 输出格式 输出一行,如果所有的单词都可以连接在一起并且可以形成一个环,那么输出Euler loop:如果所有单词都可

单词拼接 ----- 深搜

先判断这些单词能不能构成 接龙 , 能的话在排序 , 然后深搜确定接龙 . 题解 : 如果先确定所有单词的首尾字母的个数 , 如果首字母个数等于尾字母个数就不用管了 , 如果发现首字母比尾字母大1那个这个单词就是首位单词 , 末尾单词也是这样确定 , 如果发现有两个首尾的话  那么就不可能接龙成功  ,  如果成环的话 从字典序小的 单词里面找一个字母 , 排序 , 开始深搜  ,

【LeetCode-面试算法经典-Java实现】【139-Word Break(单词拆分)】

[139-Word Break(单词拆分)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. For example, given s = "leetcode", di

[转自老马的文章]用MODI OCR 21种语言

作者:马健邮箱:[email protected]发布:2007.12.08更新:2012.07.09按照<MODI中的OCR模块>一文相关内容进行修订2012.07.02按照新版Pdg2Pic的情况对内容进行补充2012.06.11标题从<在简体中文Office 2003下OCR繁体中文.日文.韩文>改为<用MODI OCR 21种语言> 目录1 安装MODI    1.1 Office 2003下安装MODI    1.2 Office 2007下安装MODI   

(每日算法)leetcode--Text Justification(格式化字符串)

要求: 给定一组字符串,按照给定长度(eg.16)格式化显示,使每一行尽可能多的单词,单词之间的空格均衡-最左侧可以稍多,左右对齐. 最后一行靠左对齐,即最右侧可以没有间隙. 如下面的例子描述: 1)每一行16个字符 2)左右对齐,空格数均衡,最左侧的间隙可以多一个空格 3)单词不可以拆开,最后一行左对齐. 原题描述: Given an array of words and a length L, format the text such that each line has exactly L

JavaScript原生对象总纲

一. javascript之Array类 创建js数组两种方式: var arr = [];  或var arr = new Array(); ()里可以指定长度,也可以不指定,指不指定都无所谓,因为js里的数组长度是可变的 1.concat(arr1,arr2,arr3......arrx): js数组合并,返回合并后的新数组,传递一个或多个数组,字符串都可以行,返回的都是一个合并的新数组(传的数组会先转成字符串再一个一个的传入进去). 2. join(): 将数组元素按指定的分隔符拼接成一字