POJ2004-Mix and Build

来源:互联网 发布:阿里巴巴淘宝城地址 编辑:程序博客网 时间:2024/05/23 01:11
  • 问题链接:【2004】(http://poj.org/problem?id=2004)
  • Description
    In this problem, you are given a list of words (sequence of lower case letters). From this list, find the longest chain of words w1, …, wn such that wi is a mixed extension of wi-1. A word A is a mixed extension of another word B if A can be formed by adding one letter to B and permuting the result. For example, “ab”, “bar”, “crab”, “cobra”, and “carbon” form a chain of length 5.

Input

The input contains at least two, but no more than 10000 lines. Each line contains a word. The length of each word is at least 1 and no more than 20. All words in the input are distinct.

Output

Write the longest chain that can be constructed from the given words. Output each word in the chain on a separate line, starting from the first one. If there are multiple longest chains, any longest chain is acceptable.

Sample Input

ab
arc
arco
bar
bran
carbon
carbons
cobra
crab
crayon
narc

Sample Output

ab
bar
crab
cobra
carbon
carbons

  • Analysis-DP算法
    len:每一个单词的长度
    pre:一个单词的前一个链接单词的位置(两者只差一个字母)
    dp:该单词往前推所能得到的最大的相连单词的长度
    letter:把单词的每一个字母分解,按字母表序存进数组里面,0-25表示a-z
    ans:记录满足条件的最大相连单词的长度
    w[22]:一个单词最长包含20个字母,该数组存储某一长度下的最后一个单词所在位置(所有单词已按长度排序)
    out:输出数组

  • 源代码

#include <iostream>#include <string.h>#include <algorithm>using namespace std;struct Node{    int len, pre, dp, letter[26];//单词长度,该单词的先前连接单词的位置,该单词往前所得到的最大链的长度,字母表    char w[22];                   //存储单词 }A[10002];int i, j, k, ans, n, w[22];           //记录最大链长度的最后一个单词的位置,单词的个数,记录各种长度的单词的最后一个单词的位置 char out[10002][22];             //存储解 bool cmp(const Node &a, const Node &b){    return a.len<b.len;         //sort函数 }int main(){    n=1;    memset(A, 0, sizeof(A));    while(cin >>A[n].w)    {        A[n].len=strlen(A[n].w);        A[n].dp=1;        for (i=0; i<A[n].len; i++)              A[n].letter[A[n].w[i]-'a']++;    //每一个字母的letter数组         n++;      }    n--;    ans=1;    sort (A+1, A+1+n, cmp);    memset(w,0,sizeof(w));    for (i=2; i<=n; i++)        if (A[i-1].len!=A[i].len)            w[A[i-1].len]=i-1;    for (i=1; i<=n; i++)        if (w[A[i].len-1])        {            for (j=w[A[i].len-1]; A[j].len==A[i].len-1; j--)            {                int flag=0;                for (k=0; k<26; k++)                    if(A[j].letter[k]>A[i].letter[k])                    {                        flag=1;                         break;                    }                if (flag)                    continue;                if(A[i].dp<A[j].dp+1)                {                    A[i].dp=A[j].dp+1;                    A[i].pre=j;                }            }            if (A[i].dp>A[ans].dp)                 ans=i;        }    n=0;    j=0;    while(ans)    {        strcpy(out[++j],A[ans].w);        ans=A[ans].pre;        n++;    }    for (i=n; i>=1; i--)        cout <<out[i]<<endl;         //根据填入性质,从后往前输出    return 0; } 
  • Problem
    一开始在输入时使用的是scanf()函数,但是总出现Runtime Error, 并且在scanf()之前加一个~运算符又不会出现错误可以通过,最后改成cin输入的