• Manthan, Codefest 16 C. Spy Syndrome 2 字典树 + dp


    C. Spy Syndrome 2

    题目连接:

    http://www.codeforces.com/contest/633/problem/C

    Description

    After observing the results of Spy Syndrome, Yash realised the errors of his ways. He now believes that a super spy such as Siddhant can't use a cipher as basic and ancient as Caesar cipher. After many weeks of observation of Siddhant’s sentences, Yash determined a new cipher technique.

    For a given sentence, the cipher is processed as:

    Convert all letters of the sentence to lowercase.
    Reverse each of the words of the sentence individually.
    Remove all the spaces in the sentence.
    For example, when this cipher is applied to the sentence

    Kira is childish and he hates losing

    the resulting string is

    ariksihsidlihcdnaehsetahgnisol

    Now Yash is given some ciphered string and a list of words. Help him to find out any original sentence composed using only words from the list. Note, that any of the given words could be used in the sentence multiple times.

    Input

    The first line of the input contains a single integer n (1 ≤ n ≤ 10 000) — the length of the ciphered text. The second line consists of n lowercase English letters — the ciphered text t.

    The third line contains a single integer m (1 ≤ m ≤ 100 000) — the number of words which will be considered while deciphering the text. Each of the next m lines contains a non-empty word wi (|wi| ≤ 1 000) consisting of uppercase and lowercase English letters only. It's guaranteed that the total length of all words doesn't exceed 1 000 000.

    Output

    Print one line — the original sentence. It is guaranteed that at least one solution exists. If there are multiple solutions, you may output any of those.

    Sample Input

    30
    ariksihsidlihcdnaehsetahgnisol
    10
    Kira
    hates
    is
    he
    losing
    death
    childish
    L
    and
    Note

    Sample Output

    Kira is childish and he hates losing

    Hint

    题意

    你有一堆单词,然后把这一堆单词都翻转了,然后拼成了一个串。

    然后现在给你一个串,让你找到原来拼的那些单词是什么。

    题解:

    字典树+dp

    直接把那个串翻转一下,就相当于倒着做了嘛

    然后我们跑dp就好了,vis[i]表示这个位置能否被转移到

    然后我们就开始在字典树上面跑啊跑,看最远能够跑到哪儿,跑到了都打一个vis[i]=1,然后记录一个pre

    然后再倒着输出一个就完了。

    注意大小写……

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+5;
    struct node{
        int ptr[26] , c ;
    };
    char s[maxn];
    int tot;
    int vis[maxn];
    int pre[maxn];
    node t[maxn];
    void init_node(node & f){
        memset(f.ptr , 0 , sizeof(f.ptr));
        f.c = 0;
    }
    void init(){
        tot = 1 ; init_node(t[0]);
    }
    inline int GetIdx(char ch){
        return ch - 'a';
    }
    void in(string str)
    {
        int cur = 0;
        for(int i = 0 ; i < str.size() ; ++ i)
        {
            int idx = GetIdx(str[i]);
            if(t[cur].ptr[idx])
                cur = t[cur].ptr[idx];
            else
            {
                init_node(t[tot]);
                cur = t[cur].ptr[idx] = tot ++ ;
            }
        }
        t[cur].c++;
    }
    void solve2(int x)
    {
        int o = x;
        x++;
        int cur=0,step=0;
        while(1)
        {
            int idx = GetIdx(s[x++]);
            if(t[cur].ptr[idx]) cur = t[cur].ptr[idx];
            else return;
            step ++;
            if(t[cur].c)vis[o+step]=1,pre[o+step]=o;
        }
    }
    int n,m;
    map<string,string> H;
    vector<string>ans;
    void solve1()
    {
        scanf("%d",&m);
    	while(m--)
    	{
            string s1,s2,s3;
            cin>>s1;
    		for(int i=0;i<s1.size();i++)
            {
    			s2+=s1[i];
    			if(s1[i]<='Z'&&s1[i]>='A')s1[i]=s1[i]+'a'-'A';
    			s3+=s1[i];
    		}
    		H[s3] = s2;
    		in(s1);
    	}
    }
    int main()
    {
        init();
        scanf("%d%s",&n,s+1);
        reverse(s+1,s+1+n);
        solve1();
        vis[0]=1;
        for(int i=0;i<n;i++)
            if(vis[i])
                solve2(i);
        while(n)
        {
            string tmp;
            for(int i=pre[n]+1;i<=n;i++)
                tmp+=s[i];
            ans.push_back(H[tmp]);
            n=pre[n];
        }
        for(int i=0;i<ans.size();i++)
            cout<<ans[i]<<" ";
        cout<<endl;
    }
  • 相关阅读:
    使用Microsoft URL Rewrite Module for IIS 7.0修改WEB.CONFIG即可实现*.HTML伪静态 无需修改应用程序映射
    我的第二个智能手机 HKC G801 严重质量问题 USB接口坏后解决办法
    JQuery的跨域方法 可跨新浪、腾讯等任意网站
    IIS7下使用MSDNURLRewriting.msi开源组件的设置
    面向对象编程,真离不开设计模式?
    jQuery 的filter(),not(),split()用法
    2008年总结
    程序中 同步和异步的经典解释 (一听就懂)
    2009年元旦前祝福 开心一下
    到底什么是SOA?
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5223572.html
Copyright © 2020-2023  润新知