zoukankan      html  css  js  c++  java
  • 100723H Obfuscation

    传送门

    题目大意

    给你一个包含n 个单词的字典,给你一篇文章,文章包括若干词典里的单词,把句子里的空格都去掉,单词的首位字母都不变,中间的字符集为乱序,问能否恢复这篇文章,使得单词都是词典里的单词,如果有唯一解,输出唯一解。

    分析

    可以将将一段字符串哈希来确定这段字符串的字母组成,在记录每一段的首字母和尾字母,这样便可以将整段字符表示出来了,在进行完预处理之后我们进行dp,用dpi表示i+1到m这一段的字符可以由先有字母表组成几个。最后如果dp0有0个则代表无法组成,大于1则有歧义,等于一则根据之前记录的nxt数组和每一段字符对应的编号将答案输出。详见代码。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define sp cout<<"---------------------------------------------------"<<endl
    #define uli unsigned long long
    #define li long long
    char bs[10002],s[10002][102];
    uli wsh[30];
    int len[10002],dp[1002],nxt[1002];
    map<uli,int>mp[28][28];
    multiset<uli>HASH[28][28];
    int main(){
          srand(time(0)+1010101);
          int n,m,i,j,t;
          for(i=0;i<28;i++)
            wsh[i]=(uli)rand()*rand()*rand()*rand()*rand()*rand()*rand()*rand();
          scanf("%d",&t);
          while(t--){
              for(i=0;i<26;i++)
                for(j=0;j<26;j++){
                    HASH[i][j].clear();
                    mp[i][j].clear();
                }
              scanf("%s",bs);
              scanf("%d",&n);
              m=strlen(bs);
            for(i=1;i<=n;i++){
              scanf("%s",s[i]);
              len[i]=strlen(s[i]);
              uli hsh=0;
              for(j=0;j<len[i];j++)
                hsh+=wsh[s[i][j]-'a'];
              HASH[s[i][0]-'a'][s[i][len[i]-1]-'a'].insert(hsh);
              mp[s[i][0]-'a'][s[i][len[i]-1]-'a'][hsh]=i;
            }
            memset(dp,0,sizeof(dp));
            memset(nxt,0,sizeof(nxt));
            dp[m]=1;
            for(i=m-1;i>=0;i--){
              uli hsh=0;
              for(j=i;j<m;j++){
                  hsh+=wsh[bs[j]-'a'];
                int x=HASH[bs[i]-'a'][bs[j]-'a'].count(hsh);
                if(x>0&&dp[j+1]){
                    dp[i]+=x*dp[j+1];
                    nxt[i]=j+1;
                }
              }
              dp[i]=min(dp[i],2);
            }
            if(dp[0]==0)puts("impossible");
              else if(dp[0]>1)puts("ambiguous");
              else {
                  for(i=0;i<m;i=nxt[i]){
                    uli hsh=0;
                    for(j=i;j<nxt[i];j++)
                      hsh+=wsh[bs[j]-'a'];
                    printf("%s ",s[mp[bs[i]-'a'][bs[nxt[i]-1]-'a'][hsh]]);
                }
                puts("");
              }
          }
          return 0;
    }
  • 相关阅读:
    Running APP 使用说明
    Android 控件八 WebView 控件
    Android 控件七 ImageView 控件
    Android 控件六 CheckBox 控件
    Android 控件五 RadioButton 控件
    Android 控件四 EditText 控件
    Android 控件三 TextView 控件实现 Button
    Android 控件二 Button
    Android 基础控件演示实例
    Android 控件一 TextView
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9346300.html
Copyright © 2011-2022 走看看