1 条题解

  • 0
    @ 2021-6-14 23:29:15

    C++ :

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int n,ans,num,h[25];
    string s[25],st,s1;
    bool Find(string A,string B)
    {
    	if(B.size()<=A.size())return 0;
    	int C=A.size();
    	for(int i=0;i<C;++i)if(B[i]!=A[i])return 0;
    	return 1;
    }
    void work(int sum,string last)
    {
    	if(sum>ans){ans=sum;/*cout<<ans<<" "<<s1<<endl;*/}
    	if(num==n*2)return;
    	int l=last.size();
    	for(int i=1;i<l;++i)
    	{
    	  string s2="";
    	  for(int j=l-i;j<l;++j)s2+=last[j];
    	  for(int j=1;j<=n;++j)
    	    if(h[j]<2)
    	    {
    		  if(Find(s2,s[j]))
    		  {
    		    string s3=s1;h[j]++;
    		    for(int k=i;k<s[j].size();++k)s1+=s[j][k];
    		    work(sum+s[j].size()-i,s[j]);
    		    s1=s3;h[j]--;
    		  }
    	    }
    	}
    }
    int main()
    {
    	memset(h,0,sizeof(h));
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)cin>>s[i];
    	cin>>st;
    	ans=st.size();s1=st;num=0;st=" "+st;
    	work(ans,st);
    	printf("%d\n",ans);
    	return 0;
    }
    
    

    Pascal :

    Program long;
    Var
       x:array[1..20]of string;
       f:array[1..20,1..20]of integer;
       start:char;
       n,i,j,k,s1,s2,min,ans:integer;
       g:array[1..20]of integer;
    procedure dfs(i,p:integer);
       var j:integer;
       begin
       for j:=1 to n do
          if (g[j]<2)and(f[i,j]<>0)then
             begin
             inc(g[j]);
             dfs(j,p+f[i,j]);
             dec(g[j]);
             end;
       if p>ans then ans:=p;
       end;
    Begin
    readln(n);
    for i:=1 to n do readln(x[i]);
    for i:=1 to n do
       for j:=1 to n do
          begin
          s1:=length(x[i]);s2:=length(x[j]);
          if s1<s2 then min:=s1-1 else min:=s2-1;
          for k:=1 to min+1 do
             if (copy(x[i],s1-k+1,k)=copy(x[j],1,k)) then break;
          if k<=min then f[i,j]:=s2-k;
          end;
    readln(start);
    for i:=1 to n do
       if start=x[i][1] then
          begin
          fillchar(g,sizeof(g),0);
          g[i]:=1;
          dfs(i,length(x[i]));
          end;
    writeln(ans);
    End.
    

    Java :

    
    import java.util.Scanner;
    
    public class Main {
    	
    	/**
    	 * 
    	 * @param words 单词数组
    	 * @param firstWord 现在为首的单个字符
    	 * @return	最长龙的数量
    	 */
    	public static int getResult(String words[],String firstWord) {
    		//	定义数组存储每个单词的访问量
    		int isVisited[] = new int[words.length];
    		int max=0;
    		int tmp;
    		//	循环查找以firstWord开头的单词
    		for(int i=0;i<words.length;i++) {
    			
    			if(firstWord.equals(words[i].substring(0, 1))) {
    				//	找到后给此单词的访问量加1
    				isVisited[i]++;
    				//	以此单词开始进行深度搜索,搜得的长度赋给tmp
    			    tmp=dfs(words, isVisited, words[i]);	    
    			    //	将该单词的访问量还原,对下一个匹配单词进行深度搜索。
    			    isVisited[i]--;
    			    //	max中存最大长度
    			    max = tmp>max?tmp:max;
    				
    			}
    		}
    		return max;
    	}
    	/**
    	 * 
    	 * @param words 单词数组
    	 * @param isVisited	访问量数组
    	 * @param preString	单词入口
    	 * @return 龙的最长长度
    	 * 	at
      		touch
    		
      		cheat
      		choose
      		tact   以这几个单词为例解释
    	 */
    	public static int dfs(String words[],int isVisited[], String preString) {
    		//	是否还有后面单词的标志位,如果遍历完单词数组还是人没有找到后继单词则此状态为false,直接输出次单词的长度。比如最后一个接到choose,
    		//	单词列表中中没有以e、se、ose、oose、hoose为首的单词,所以直接返回choose的长度。
    		boolean hasWord = false;
    		//	将找后继的单词从后面开始截,比如 找touch的后继,从单词后面截先解个h,然后遍历单词列表中以h开头的,若没有再截ch,找ch开头的,
    		//	若还是没找到,至到截到ouch,因为题目要求不能有包含关系,所以不能截到0
    		for(int j=preString.length()-1;j>0;j--) {
    			int max=0;
    			//	是否还需要再截的标志位,因为截的位数越少,所连接的龙就越长,所以只要第一次截出来的单词在单词列表中能匹配到,就不用往后再截。
    			//	例如,cheat,第一次截t,,遍历发现有t开头的,这个时候我们没有必要继续往后截,因为cheat+touch→cheatouch,长度为两个单词长度减j,j越小,龙越长
    			boolean preFlag=false;
    			for(int i=0;i<words.length;i++) {
    				int tmp=0;
    				//	首先单词表中的长度要大与截的单词长度,其次判断单词表是否有开头为所截单词的单词,最后还得满足找到的单词的访问量小于2
    					if(words[i].length()>preString.length()-j&&
    							preString.substring(j, preString.length()).equals(words[i].substring(0, preString.length()-j))
    							&&isVisited[i]<2) {
    						//	如果以上条件满足,则表明已经找到了匹配单词,所以后面不用截了,标志位preFlag变为true
    						preFlag = true;
    						//	表示该单词后面还有单词
    						hasWord = true;
    						//	将该单词访问量加1
    						isVisited[i]++;
    						//	继续搜索后面的单词,并把连接最长的存入max,以touch为例,当截到ch时,遍历单词列表,第一次找到cheat,然后以cheat
    						//	为下一个单词继续搜,并把长度记录到tmp中与max比较,然后遍历到单词choose发现也可以,然后以choose往下搜,最后将以
    						//	cheat和choose往下搜中长度最长的返回。
    						tmp = j+dfs(words, isVisited, words[i]);
    						//	访问量恢复,为下一次搜索做准备
    						isVisited[i]--;
    						max = tmp>max?tmp:max;	
    					}
    								
    			}
    			//	preFlag为true时,表示不用往下截了,返回最大值即可
    			if(preFlag)
    				return max;
    		}
    		//	如果没进循环,表示找不到他的后继了,直接返回单词长度
    		if (!hasWord) 
    			return preString.length();
    		return 0;
    	}
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Scanner in = new Scanner(System.in);
    		int n = in.nextInt();
    		String words [] = new String[n];
    		for (int i=0;i<n;i++) {
    			String temp = in.next();
    			words[i] = temp;
    		}
    		String start = in.next();
    //		for (int i=0;i<words.length;i++) {
    //			System.out.println(words[i]);
    //		}
    		//System.out.println(words);
    		//System.out.println(start);
    		int count = getResult(words,start);
    		System.out.print(count);
    		
    	}
    
    }
    
    
    • 1

    信息

    ID
    205
    时间
    1000ms
    内存
    125MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者