• [NOIP2000] 提高组 洛谷P1019 单词接龙


    题目描述

    单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。

    输入输出格式

    输入格式:

     

    输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.

     

    输出格式:

     

    只需输出以此字母开头的最长的“龙”的长度

     

    输入输出样例

    输入样例#1:
    5
    at
    touch
    cheat
    choose
    tact
    a
    
    输出样例#1:
    23           (连成的“龙”为atoucheatactactouchoose)   

    说明

    NOIp2000提高组第三题

    数据不大,暴力吧。

    预处理出每个单词连接另一个单词时可以增加的长度,然后在可以连接的单词之间连边,边权就是增加的长度,暴搜找最长路。

     1 /*By SilverN*/
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int f[2000][2000];
     8 char c[60][200];
     9 int n;
    10 char a;
    11 int used[200];
    12 int ans=0;
    13 int leng=0;
    14 int pd(int p1,int p2){
    15     int l1=strlen(c[p1]);
    16     int i,j;
    17     for(i=l1-1;i>=1;i--)
    18         if(c[p1][i]==c[p2][0]){
    19 //            printf("mark: %d
    ",i);
    20             bool flag=0;
    21             for(j=1;j<l1-i;j++)if(c[p1][i+j]!=c[p2][0+j])
    22                 {flag=1;break;}
    23             if(flag)continue;
    24             return strlen(c[p2])-(l1-i);//两词接续能增加的长度 
    25         }
    26     return -1;
    27 }
    28 void work(int tot){
    29     int i,j;
    30     for(i=1;i<=tot;i++)
    31       for(j=1;j<=tot;j++)
    32         f[i][j]=pd(i,j);
    33     return;
    34 }
    35 void dfs(int pos){
    36     ans=max(ans,leng);
    37     int i,j;
    38     for(i=1;i<=n;i++){
    39         if(f[pos][i]>0 && used[i]<2){
    40             used[i]++;
    41             leng+=f[pos][i];
    42 //            if(leng>ans)ans=leng;
    43             dfs(i);
    44             leng-=f[pos][i];
    45             used[i]--;
    46         }
    47     }
    48     return;
    49 }
    50 int main(){
    51     scanf("%d",&n);
    52     int i,j;
    53     for(i=1;i<=n;i++){
    54         cin>>c[i];
    55 //        strcpy(c[n+i],c[i]);
    56     }
    57     cin>>a;
    58     work(n);
    59     for(i=1;i<=n;i++){
    60         if(c[i][0]==a){
    61             leng=strlen(c[i]);
    62             used[i]++;
    63             dfs(i);
    64             used[i]--;
    65         }
    66     }
    67     printf("%d",ans);
    68     return 0;
    69 }
  • 相关阅读:
    【非技术】谈谈业务6W+H
    WinForm二三事(三)Control.Invoke&Control.BeginInvoke
    企业应用架构模式读书笔记(一)
    WinForm二三事(四)界面布局(上)
    WinForm二三事(二)异步操作
    WinForm二三事(一)消息循环
    白话基础之虚拟存储器
    不清楚自己的位置,会走很多弯路
    WinForm二三事(一)补遗
    技术、业务、市场
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5956089.html
Copyright © 2020-2023  润新知