2015蓝桥杯决赛 密文搜索(字符串)

来源:互联网 发布:37诸神黄昏进阶数据 编辑:程序博客网 时间:2024/05/21 21:50

题目:

标题:密文搜索

福尔摩斯从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 , 不能通过工程设置而省略常用头文件。

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

思路:

看了题目我以为是KMP,于是去看了KMP,最后发现,这其实也是一个思路题

因为求的是所有的排列的情况的匹配总数,所以我们分几个步骤:
1. 把原字符串,每8个字母统计一下个数,存进一个数组
2. 当输入n组字符串时,统计每一个字符串中字母的个数,然后和存储的字符串进行比较,如果字母个数相同,计数器+1就行

代码:

#include<cstdio>#include<cstring>#include<cctype>#include<string>#include<set>#include<iostream>#include<stack>#include<cmath>#include<queue>#include<vector>#include<algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define mod 10000007#define debug() puts("what the fuck!!!")#define N 1111111#define M 10000020#define ll longlongusing namespace std;char str[M],s[20];int a[M][30],b[30];int main(){    mem(a,0);    int n;    scanf("%s%d",str,&n);    int len=strlen(str);    len-=8;    for(int i=0; i<=len; i++)        for(int j=i; j<=i+7; j++)            a[i][str[j]-'a']+=1;//记录一下对应字母的个数    int sum=0;    while(n--)    {        int flag;        mem(b,0);        scanf("%s",s);        int len2=strlen(s);        for(int i=0; i<len2; i++)            b[s[i]-'a']+=1;        for(int i=0; i<=len; i++)        {            flag=1;            for(int j=0; j<26; j++)            {                if(a[i][j]!=b[j])                {                    flag=0;                    break;                }            }            if(flag==1)//字母个数完全相等的时候计数                sum++;        }    }    printf("%d\n",sum);    return 0;}
原创粉丝点击