zoukankan      html  css  js  c++  java
  • 18.04.08 luoguP1019 单词接龙

    题目描述

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

    输入输出格式

    输入格式:

     

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

     

    输出格式:

     

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

     

    输入输出样例

    输入样例#1: 
    5
    at
    touch
    cheat
    choose
    tact
    a
    
    输出样例#1: 
    23
    

    说明

    (连成的“龙”为atoucheatactactouchoose)

    NOIp2000提高组第三题

     1 #include <iostream>
     2 #include <string>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <stdlib.h>
     6 
     7 using namespace std;
     8 const int maxn = 50;
     9 string word[maxn];
    10 int flag[maxn], n;//已遍历为1
    11 char head;
    12 int con1[maxn][maxn];//存储当两个词有序连接的时候,第一个词的衔接点是第几个字母
    13 int maxlen = 0, tmplen = 0;
    14 
    15 void connect() {
    16     for (int i = 1; i <= 2 * n; i++)
    17         for (int j = 1; j <= 2 * n; j++) {
    18             if (((word[i].find(word[j])<999&&word[i].find(word[j]) >=0) || (word[j].find(word[i])<999) && word[j].find(word[i]) >= 0) && word[i] != word[j])
    19                 continue;
    20             int l = word[j].length(),_l=word[i].length();
    21             for (int k = 1; k<l; k++) {
    22                 int tmp = word[i].rfind(word[j].substr(0,k));
    23                 if (tmp<999&&tmp>=0&&(_l-tmp)==k)
    24                 {
    25                     con1[i][j] = tmp;
    26                     break;
    27                 }
    28             }
    29         }
    30 }
    31 
    32 void dfs(int h) {
    33     for (int i = 1; i <= 2 * n; i++) {
    34         if (!flag[i] && con1[h][i]) {
    35             flag[i] = 1;
    36             int l1 = word[h].length(), l2 = word[i].length();
    37             int addlen = -(l1 - con1[h][i] - 1) + l2 - 1;
    38             tmplen += addlen;
    39             maxlen = max(tmplen, maxlen);
    40             dfs(i);
    41             tmplen -= addlen;
    42             flag[i] = 0;
    43         }
    44     }
    45 }
    46 
    47 int main()
    48 {
    49     scanf("%d", &n);
    50     for (int i = 1; i <= n; i++) {
    51         cin >> word[i];
    52         word[n + i] = word[i];
    53     }
    54     scanf("%s", &head);
    55     connect();
    56     for (int i = 1; i <= n; i++) {
    57         if (word[i][0] == head)
    58         {
    59             flag[i] = 1;
    60             tmplen = word[i].length();
    61             maxlen = max(tmplen, maxlen);
    62             dfs(i);
    63             flag[i] = 0;
    64         }
    65     }
    66     printf("%d
    ", maxlen);
    67     return 0;
    68 }
    View Code

    WA1:泪奔!

    看成只要两个词中间有重叠就可以接!

    debug了好久才发现!是首尾相接!

    这么错的恐怕只有我一个了

    最近学c++所以用了string

    WA2:没有考虑单个单词的情况(数据#4)

    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    最大子数组1
    大道至简阅读笔记03
    I-think-3
    第3周学习进度
    大道至简阅读笔记02
    四则运算题3
    大道至简阅读笔记01
    第2周学习进度
    构建之法阅读笔记03
    按Right-BICEP的测试用例
  • 原文地址:https://www.cnblogs.com/yalphait/p/8745909.html
Copyright © 2011-2022 走看看