2015(第六届)蓝桥杯c/c++B组决赛 密文搜索

密文搜索
时间限制:3.0s 内存限制:512.0MB

问题描述
福尔摩斯从X星收到一份资料,全部是小写字母组成。
他的助手提供了另一份资料:许多长度为8的密码列表。
福尔摩斯发现,这些密码是被打乱后隐藏在先前那份资料中的。

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

数据格式:

输入第一行:一个字符串s,全部由小写字母组成,长度小于1024*1024
紧接着一行是一个整数n,表示以下有n行密码,1<=n<=1000
紧接着是n行字符串,都是小写字母组成,长度都为8

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

例如:
用户输入:
aaaabbbbaabbcccc
2
aaaabbbb
abcabccc

则程序应该输出:
4

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


思路:

      不需要进行模式匹配,统计密码中各字符的个数,判断与主串中长度为8的子串的各字符的个数是否相等即可,可将字母转化为数字进行比较更为方便

      注意:
            开辟大数组时,要将其写在主函数外

#include
#include
#include
#include

using namespace std;

char s[1100000];
int a[1100000];
int flag1[123];
int flag2[123];

int main()
{
	memset(s,0,sizeof(s));
	int i,j,k,r;
	int sum=0;
	cin>>s;
	i=0;
	while(s[i]!='\0')
	{
		a[i]=(int)s[i];//将字母转化为int类型的数字,a-z为97-122
		i++;
	}
	int len=i;
	int n;
	cin>>n;
	char b[9];
	for(i=0;i<n;i++)
	{
		cin>>b;
		for(j=0;j<8;j++)
			flag1[(int)b[j]]++;//统计密码中各字符的个数
		for(k=0;k<len-7;k++)
		{
			for(r=k;r<k+8;r++)
				flag2[a[r]]++;//统计主串中长度为8的子串中各字符的个数
			for(r=97;r<123;r++)
				if(flag1[r]!=flag2[r])//判断,密码与子串的各字符的个数是否相等
					break;
			if(r==123)
				sum++;
			memset(flag2,0,sizeof(flag2));
		}
		memset(flag1,0,sizeof(flag1));
	}
	cout<<sum;
    return 0;
}

你可能感兴趣的:(2015(第六届)蓝桥杯c/c++B组决赛 密文搜索)