zoukankan      html  css  js  c++  java
  • 密文搜索

    福尔摩斯从X星收到一份资料,全部是小写字母组成。

    他的助手提供了另一份资料:许多长度为8的密码列表。

    福尔摩斯发现,这些密码是被打乱后隐藏在先前那份资料中的。

    请你编写一个程序,从第一份资料中搜索可能隐藏密码的位置。要考虑密码的所有排列可能性。

    数据格式:

    输入第一行:一个字符串s,全部由小写字母组成,长度小于1024*1024

    紧接着一行是一个整数n,表示以下有n行密码,1<=n<=1000

    紧接着是n行字符串,都是小写字母组成,长度都为8

    要求输出:

    一个整数, 表示每行密码的所有排列在s中匹配次数的总和。

    例如:

    用户输入:

    aaaabbbbaabbcccc
    2
    aaaabbbb
    abcabccc
    

    则程序应该输出:

    4
    

    这是因为:第一个密码匹配了3次,第二个密码匹配了1次,一共4次。

    资源约定:

    峰值内存消耗 < 512M CPU消耗 < 3000ms

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

    注意: main函数需要返回0

    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

    提交时,注意选择所期望的编译器类型。

    每个点保存以自己为最后一个点的连续八个点的状态,然后暴力判断每个密码和密文中任意连续八个字符的子串字符类型和数量匹配就加1。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    char str[1024 * 1024],psw[9];
    int num[100000][27],cc = 0;
    int n;
    int main()
    {
        scanf("%s%d",str,&n);
        int m = strlen(str);
        for(int i = 0;i < m;i ++)
        {
            for(int j = i;j <= i + 7 && j < m;j ++)
            {
                num[j][str[i] - 'a'] ++;
            }
        }
        for(int i = 0;i < n;i ++)
        {
            scanf("%s",psw);
            int c = 0,d[27],p[27] = {0};
            for(int j = 0;j < 8;j ++)
            {
                if(!p[psw[j] - 'a'])
                    d[c ++] = psw[j] - 'a';
                p[psw[j] - 'a'] ++;
            }
            for(int j = 7;j < m;j ++)
            {
                int flag = 1;
                for(int k = 0;k < c;k ++)
                {
                    if(p[d[k]] != num[j][d[k]])
                    {
                        flag = 0;
                        break;
                    }
                }
                cc += flag;
            }
        }
        printf("%d",cc);
    }
    View Code

     2019重做,没有看以前的,以8为区间大小,更新各字符个数,进行判断。

    代码:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    char s[1 << 20 + 1];
    char t[8];
    int d[26],e[26];
    int n,c;
    bool check() {
        for(int i = 0;i < 26;i ++) {
            if(d[i] != e[i]) return false;
        }
        return true;
    }
    int main() {
        scanf("%s%d",s,&n);
        for(int i = 0;i < n;i ++) {
            scanf("%s",t);
            memset(d,0,sizeof(d));
            memset(e,0,sizeof(e));
            for(int j = 0;t[j];j ++) {
                d[t[j] - 'a'] ++;
                e[s[j] - 'a'] ++;
            }
            c += check();
            for(int j = 8;s[j];j ++) {
                e[s[j - 8] - 'a'] --;
                e[s[j] - 'a'] ++;
                c += check();
            }
        }
        printf("%d",c);
    }
    View Code
  • 相关阅读:
    outer join,inner join,left join,right join的区别是什么?
    hdu 数值转换
    hdu 4
    hdu
    NET Framework数据提供程序的4种核心对象及其作用
    时间复杂度和空间复杂度
    hdu 1004
    hdu 级数求和
    [记录]微软生成wsdl代理类
    css position:relative 在IE6, 7下有bug
  • 原文地址:https://www.cnblogs.com/8023spz/p/8947331.html
Copyright © 2011-2022 走看看