[蓝桥杯 2015 国 B] 密文搜索

[蓝桥杯 2015 国 B] 密文搜索

hash+滑动窗口思想(不是滑动窗口实现),就像栈不一定是真的数据结构的栈啊喂(#`O′)

这个题我debug半天结果发现是map没运用的很熟
map mp;++mp[haha];
结果key-haha的value如果操作至零,haha这个key还在… 所以得特判:if(x.second)

这个题是用hash+滑动窗口思想(不是滑动窗口实现),比较简单,就是看题得看老半天
滑动窗口?因为我不想用substr()(忘了其实…
[蓝桥杯 2015 国 B] 密文搜索_第1张图片

[蓝桥杯 2015 国 B] 密文搜索_第2张图片

题目描述

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

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

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

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

输入格式

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

紧接着一行是一个整数 n , n, n, 表示以下有 n n n 行密码, 1 ≤ n ≤ 1000 1 \le n \le 1000 1n1000

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

输出格式

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

样例 #1

样例输入 #1

aaaabbbbaabbcccc
2
aaaabbbb
abcabccc

样例输出 #1

4

提示

第一个密码匹配了 3 3 3 次,第二个密码匹配了 1 1 1 次,一共 4 4 4 次。

时限 3 秒, 512M。蓝桥杯 2015 年第六届国赛

CODE

#include
using namespace std;
string str;
//queueque;本来滑动窗口做了一半才发现,只是借鉴思想而非真的去做,故舍弃
map<char,int>mp;//可以unorderedmap再最后排序 
map<string,int>alls;
int main(){
	ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);
	cin>>str;
	for(int i=0;i<str.size();++i){
	//滑动下一个子串的开头索引
		++mp[str[i]];
		if(i>6){//如果已有八个元素了i表示第七,大于第七就是第八,始终维护八个大小空间的滑动窗口,当然库函数substr当我没说
			string s;
			for(const auto& x:mp){
				if(x.second){
					s.push_back(x.first);
					s+=to_string(x.second);
				}
			}
			++alls[s];//字符串所有子串的可能性排列哈希
			--mp[str[i-7]];
		//将窗口顶部的弹出(实际就是舍弃窗口顶部元素的价值)--->滑动窗口思想啊!
		}
	}
//母文本的子串哈希	for(auto x:alls)cout<

	//密码串的排列哈希
	int n;cin>>n;
	int ans=0;
	for(int i=0;i<n;++i){
		map<char,int>pwd_list;//容量26的密码哈希列表 
		string pwd;cin>>pwd;
		int loop=8;
		while(loop--)++pwd_list[pwd[loop]];
		string s2;
		for(const auto& x:pwd_list){
//			密码的组合哈希cout<
			s2.push_back(x.first);
			s2+=to_string(x.second);
		}
		ans+=alls[s2];
	}
	cout<<ans<<endl;

	return 0;
}
/*
avcccdedfa
2
vaceddcc
aadedeaa
*/
/*
自己写的测试样例
asdasdaswqeqwdsadvvvvqwioeuqsadksadasdasczxczeqwe
3
asdasdas
vdvqvwvi
zcznnnnn
3

*/

你可能感兴趣的:(哈希表,洛谷刷题,队列,蓝桥杯)