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;
    }
  • 相关阅读:
    Docker 命令收集
    Linux环境变量总结
    Docker 安装Hadoop HDFS命令行操作
    Docker 搭建Spark 依赖singularities/spark:2.2镜像
    Docker 搭建Spark 依赖sequenceiq/spark:1.6镜像
    kill命令
    每天一个linux命令:ps命令
    swoole执行外部程序称为进程
    php休眠微秒
    php监控文件变化
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9346300.html
Copyright © 2011-2022 走看看