zoukankan      html  css  js  c++  java
  • nyoj--99--单词拼接(欧垃图判定+输出)

    单词拼接

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:5
    描述

    给你一些单词,请你判断能否把它们首尾串起来串成一串。

    前一个单词的结尾应该与下一个单词的道字母相同。

    aloha

    dog

    arachnid

    gopher

    tiger

    rat

     

    可以拼接成:aloha.arachnid.dog.gopher.rat.tiger

    输入
    第一行是一个整数N(0<N<20),表示测试数据的组数
    每组测试数据的第一行是一个整数M,表示该组测试数据中有M(2<M<1000)个互不相同的单词,随后的M行,每行是一个长度不超过30的单词,单词全部由小写字母组成。
    输出
    如果存在拼接方案,请输出所有拼接方案中字典序最小的方案。(两个单词之间输出一个英文句号".")
    如果不存在拼接方案,则输出
    ***
    样例输入
    2
    6
    aloha
    arachnid
    dog
    gopher
    rat
    tiger
    3
    oak
    maple
    elm
    样例输出
    aloha.arachnid.dog.gopher.rat.tiger
    ***
    来源
    Waterloo local 2003.01.25 /POJ
    上传者

    张云聪


    这道题就是判断是否有欧拉路,然后输出欧垃迹,中间的数据处理有些麻烦,将单词掐头去尾,记录入度出度,因为最多用到26个字母,所以如果一个字母的入度和出度相差2或者更多,就不会有欧垃路,如果入度出度相差为一的字母数超过1,也不会有欧拉路,如果有,那麽就开始dfs,dfs找的时候从一个度数为奇数的点开始,知道全部找完,那么就输出欧垃迹,否则就是不存在


    <pre name="code" class="cpp">#include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    struct node
    {
    	char s[30];
    	int f,l;
    }word[1010];
    int in[1010],out[1010],vis[1010],order[1010],m;
    int f()
    {
    	int x1,x2,ans=0;
    	x1=x2=0;
    	for(int i=0;i<26;i++)
    	{
    		if(abs(in[i]-out[i])>=2)
    		return -1;
    		else if(in[i]-out[i]==1)
    		x1++;
    		else if(in[i]-out[i]==-1)
    		{
    			x2++;
    			ans=i;
    		}
    	}
    	if(x1>1||x2>1)
    	return -1;
    	else if(x1==0)
    	{
    		for(int i=0;i<26;i++)
    		if(out[i])
    		return i;//因为我记录的出度是一个最后一个字母,所以从这儿开始dfs
    	}
    	else
    	return ans;
    }
    int cmp(node a,node b)
    {
    	return strcmp(a.s,b.s)<0;
    }
    bool dfs(int st,int cnt)
    {
    	if(cnt==m)
    	return 1;
    	for(int i=0;i<m;i++)
    	{
    		if(word[i].f<st||vis[i])
    		continue;
    		else if(word[i].f>st)
    		return false;
    		vis[i]=1;
    		order[cnt]=i;
    		if(dfs(word[i].l,cnt+1))
    		return 1;
    		vis[i]=0;
    	}
    	return false;
    }
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d",&m);
    		memset(vis,0,sizeof(vis));
    		memset(in,0,sizeof(in));
    		memset(out,0,sizeof(out));
    		memset(order,0,sizeof(order));
    		for(int i=0;i<m;i++)
    		{
    			scanf("%s",word[i].s);//单词掐头去尾,记录入度出度 
    			int l=strlen(word[i].s);
    			word[i].f=word[i].s[0]-'a';
    			word[i].l=word[i].s[l-1]-'a';
    			in[word[i].l]++;
    			out[word[i].f]++;
    		}
    		int start=f();
    		if(start==-1)
    		{
    			printf("***
    ");
    			continue;
    		}
    		sort(word,word+m,cmp);
    		if(!dfs(start,0))
    		{
    			printf("***
    ");
    			continue;
    		}
    		printf("%s",word[order[0]].s);
    		for(int i=1;i<m;i++)
    		printf(".%s",word[order[i]].s);
    		printf("
    ");
    	}
    	return 0;
    } 


    
    

  • 相关阅读:
    Vue使用watch监听一个对象中的属性
    小程序 显示对话框 确定-取消
    【微信小程序】 wx:if 与 hidden(隐藏元素)区别
    vue项目移植tinymce踩坑
    XMLHttpRequest.withCredentials 解决跨域请求头无Cookie的问题
    appJSON["window"]["navigationBarTextStyle"] 字段需为 black 或 white
    Java写 插入 选择 冒泡 快排
    编码表理解
    Centos yum安装java jdk1.8
    Java Hibernate和.Net EntityFramework 如何在提交事务之前 就拿到需要新增实体的Id
  • 原文地址:https://www.cnblogs.com/playboy307/p/5273531.html
Copyright © 2011-2022 走看看