单词接龙


单词接龙:是指一组单词序列,任何两个相邻的单词满足前一个单词的尾字母和后一个单词的首字母相同。 

接龙长度:接龙中所有单词长度之和。 

如单词:tea, cat, dog, aid, fish

可以形成单词接龙:cat tea aid dog

其中cat为龙头,dog为龙尾 

接龙包含的单词个数为4

接龙长度为12

规格说明:

  • 单词由全小写字母组成,以字符串形式给定,即以’\0’结束(用例保证 

  • 单词长度和数量均无限制 

  • 一条单词接龙中每个单词只能使用一次 

功能说明:

定义 

1最少接龙:单词数量最少的接龙 

2最短接龙:长度最短的接龙 

给定一套单词库,请根据指定的龙头和龙尾,实现以下功能: 

1、计算最少接龙包含的单词个数 

2、计算最短接龙的长度 

示例: 

单词库由ab,beeec,bd,dc,cb五个单词组成,以ab为龙头,cb为龙尾的接龙中: 

最少接龙:ab beeec cb(含有3个单词) 

最短接龙:ab bd dc cb(接龙长度为8

 

功能:添加单词

输入:单词

输出:无

 

功能:获取最少接龙的单词个数

输入:head 龙头 

     tail     龙尾 

输出:单词个数(如果不能形成接龙、指定龙头龙尾不存在、龙头龙尾相同等,返回-1 

 

功能:获取最短接龙的长度

输入:head 龙头 

     tail     龙尾 

输出:接龙的长度(如果不能形成接龙、指定龙头龙尾不存在、龙头龙尾相同等,返回-1 

 

 

 
知识点:  
题目来源:  内部整理 
练习阶段:  挑战 
运行时间限制: 10Sec
内存限制: 128MByte
输入:  

添加的一组单词序列,一行字符串,每个单词以空格隔开,如ab beeec bd dc cb

获取最少接龙的单词个数和获取最短接龙的长度,一行字符串,包括2个单词,分别是龙头单词和龙尾单词,如ab cb

 
输出:  

2个整数,获取最少接龙的单词个数和获取最短接龙的长度,一个空格隔开

 
样例输入:
ab beeec bd dc cb
ab cb
                   
样例输出:
3 8
                    
答案提示:

 

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

	/**
	 * @param args
	 */
	public static String head ="";
	public static String end ="";
	public static List result = new ArrayList();
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scan = new Scanner(System.in);// 接收控制台输入的信息
		String str = scan.nextLine();
		
		String headend = scan.nextLine();
		String[] myarr = headend.split(" ");
		
		List my = new ArrayList();
		String[] arr = str.split(" ");
		for(int i = 0;i my) 
	{
		for(int j=0;j

主要用回溯法,和8皇后类似

开始有3个用例没有过,实在是检查不出来,每次只能提交一次真是坑爹,后来搜了下论坛上,看别人说错误要输出-1,-1;就改成这样了,不知道能不能通过


这是论坛上别人c++代码,貌似通过了,懒得试了

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
void Find_Shortest_Path(int v,int *dist,bool len_or_count);
typedef struct Node
{
 string word;      //存储单词
 struct Node *next;
    int index;        //存储该节点在容器中索引,图中每一个节点有一个唯一的索引值,一个节点的邻接节点构成单链表中节点的index值就是对应的
}NODE;                //指针数组中(或说图中)的索引为index的节点,单链表中的节点其实是图中节点的副本,索引(编号)一样  ,都表示index这个节点
bool *flag_str;       //存储某个节点是否被访问过的标志,这个标志必须单独,不能放到上面的节点中
vector nodvec; //头节点容器
int f_index,l_index;              //存储龙头和龙尾在容器中的索引
int result_len=60000,result_count=60000;  //查找的结果
int main()
{
 string line,temp,first,last;
 vector vec; 
 int index=0;
    getline(cin,line);
 istringstream istr(line);
 while(istr>>temp)
  vec.push_back(temp);
 sort(vec.begin(),vec.end());
 vector::iterator iter=unique(vec.begin(),vec.end());
 vec.erase(iter,vec.end());
 cin>>first>>last;
 iter=vec.begin();
 bool f_flag=false,l_flag=false;
 while(iter!=vec.end())          //判断龙头和龙尾单词是否存在,是否相等
 {
     if(*iter==first)
  { 
   f_flag=true;
   f_index=iter-vec.begin();
  }
  if(*iter==last)
  { 
   l_flag=true;
   l_index=iter-vec.begin();
  }
     ++iter;
 }
 if(first==last || !(f_flag && l_flag))
 {
  cout << -1 << " "  << -1 << endl;
return -1;
 }
 iter=vec.begin();
 flag_str=new bool[vec.size()]();    //动态分配标志数组,标示某个节点是否已经加入到最短路径中
 while(iter!=vec.end())    //将头节点的地址放到一个容器中
 {
  NODE *p=new NODE();
  p->word=*iter;
  p->next=NULL;
  p->index=index++;
  flag_str[p->index]=false;
  nodvec.push_back(p);
  ++iter;
 }
 vector::iterator pfiter=nodvec.begin(),psiter=nodvec.begin();
 while(pfiter!=nodvec.end())      //形成图
 {
  psiter=nodvec.begin();
  while(psiter!=nodvec.end())
  {
   if((*pfiter)->word!=(*psiter)->word)  //不要让自己是自己的后继
   {
    if((*psiter)->word[(*psiter)->word.length()-1]==(*pfiter)->word[0])
    {
     NODE *p=*psiter;
     while(p->next!=NULL) 
      p=p->next;
     NODE *q=new NODE();
     q->index=(*pfiter)->index;
     q->word=(*pfiter)->word;
     q->next=NULL;
     p->next=q;
    }
   }
   ++psiter ;
  }
     ++pfiter;
 }
 int *dist=new int[nodvec.size()]();
 Find_Shortest_Path(f_index,dist,false);   //查找单词接龙所有路径中单词的最少个数
 for(int i=0;inext;
  delete q;
  while(p!=NULL)
  {
      q=p;
   p=p->next;
   delete q;
  }
 }
 delete [] flag_str;
 delete [] dist;
 if(result_len==60000 || result_count==60000)
 {
  cout << -1 << " "  << -1 << endl;
return -1;
 }
 else
     cout<::iterator iter;
 iter=nodvec.begin();
 NODE *p=nodvec[v]->next;
 //初始化路径长度(单词长度和单词个数)
 while(p!=NULL)  //初始化从头节点能直达的节点
 {
  if(len_or_count)
      dist[p->index]=p->word.length();
  else
   dist[p->index]=1;
  flag_str[p->index]=true;  //标示为true的为已经初始化的节点,后面要重新置为false
  p=p->next;
 }
 while(iter!=nodvec.end())     //初始化从头节点不能直达的节点
 {
  if((*iter)->index!=v)   //自己的不搜索
  {
   if(flag_str[(*iter)->index])
    flag_str[(*iter)->index]=false;
   else
    dist[(*iter)->index]=60000;    
  }
  else                    //置自己的标志
   flag_str[(*iter)->index]=true;
     ++iter;
 }
 for(int i=1;iindex] && dist[j]index]=true;
  p=nodvec[vt]->next;
  while(p!=NULL)
  {
   if(!flag_str[p->index] && minval+p->word.length()index])
   {
    if(len_or_count)
       dist[p->index]=minval+p->word.length();
    else
       dist[p->index]=minval+1;
   }
   p=p->next;
  }
     if(vt==l_index)   //已经找到了目标了
  {
   if(len_or_count)   
       result_len=dist[vt]+nodvec[v]->word.length();
   else
    result_count=dist[vt]+1;
   break;
  }
 }
}




你可能感兴趣的:(2014华为oj)