CF#633C Spy Syndrome 2 DP+二分+hash

Spy Syndrome 2

題意

如今對某個英文句子,進行加密:c++

  1. 把全部的字母變成小寫字母
  2. 把全部的單詞反過來
  3. 去掉單詞之間的空格

好比:Kira is childish and he hates losing加密

加密爲ariksihsidlihcdnaehsetahgnisolspa

如今給出加密後的句子,以及m個單詞(每一個單詞能夠重複使用),輸出原來的句子。code

思路

使用dp[i]表示第i個字母做爲句子最後一個單詞的開頭所在的單詞編號。cdn

dp值爲0表示不能組成句子。排序

對於每一個單詞hash一下,按照每一個單詞的hash值從小到大排序。get

遍歷加密後的句子,對於每一個i,往前尋找第一個j使得[i,j]爲一個單詞(最多1000次,單詞長度最大爲1000),紀錄這個單詞的編號。hash

對於每個j,使用二分判斷全部的單詞中是否存在當前的hash值,若是存在那麼[i,j]就是一個合法的單詞。
若是dp[j-1]==0,說明第j-1個字符做爲最後一個單詞的開頭不合法,那麼[i,j]做爲一個單詞確定不合法,跳過。it

而後DFS輸出一下。class

這個思路我就是莽一發,居然沒超時685ms

正解好像是字典樹+dfs,不過字典樹還沒學。

代碼

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;

int dp[N];
char s[N];
struct note
{
    int id,val;
    char s[1010];
    bool operator <(const note&a) const
    {
        return val<a.val;
    }
} arr[N],now;
bool cmp(note a,note b)
{
    return a.id<b.id;
}
void dfs(int pos)
{
    if(pos==0) return ;
    int len=strlen(arr[dp[pos]].s);
    dfs(pos-len);
    for(int i=0; i<len; i++)
        printf("%c",arr[dp[pos]].s[i]);
    printf(" ");
}
int main()
{
    int lens;
    scanf("%d%s",&lens,s+1);
    int m;
    scanf("%d",&m);
    for(int i=1; i<=m; i++)
    {
        arr[i].val=0;
        scanf("%s",arr[i].s);
        arr[i].id=i;
        int lent=strlen(arr[i].s);
        for(int j=0; j<lent; j++)//計算當前單詞的hash值
        {
            int tmp=arr[i].s[j]-'a'+1;
            if(arr[i].s[j]>='A'&&arr[i].s[j]<='Z')
                tmp+=32;
            arr[i].val=(arr[i].val*26%mod+tmp)%mod;
        }
    }
    sort(arr+1,arr+1+m);
    dp[0]=1;
    for(int i=1; i<=lens; i++)
    {
        int tmp=0;
        for(int j=i; j>max(0,i-1000); j--)//最多遍歷1000位
        {
            tmp=(tmp*26%mod+(s[j]-'a'+1))%mod;
            if(!dp[j-1]) continue;//若是dp[j-1]不能組成句子,當前位沒有繼續的必要
            now.val=tmp;
            int pos=(int)(lower_bound(arr+1,arr+1+m,now)-arr);
            if(pos!=m+1&&arr[pos].val==tmp)
            {
                dp[i]=arr[pos].id;//紀錄單詞編號
                break;
            }
        }
    }
    sort(arr+1,arr+1+m,cmp);
    dfs(lens);
    printf("\n");
    return 0;
}
/*
7
ihereht
3
HI
Ho
there
*/
相關文章
相關標籤/搜索