[蓝桥杯][2015年第六届真题]密文搜索 模拟+双指针

蓝桥杯历年真题题目及题解目录汇总 

 

题目链接:https://www.dotcpp.com/oj/problem1828.html

 

题目描述


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

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

输入

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

输出

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

样例输入

aaaabbbbaabbcccc
2
aaaabbbb
abcabccc

样例输出

4

 字符串匹配,双指针,时间复杂度已经优化到线性了,但是呢,早年的蓝桥杯的数据规模有点诡异,我估算了下,1e9,不过实际的规模没那么夸张,果断AC了org

题目意思说白了就是只要扫过字符串中,和下面的密码出现的字母数相同就好

import java.util.Scanner;

public class 密文搜索_双指针 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		char[] ch = in.next().toCharArray();
		n = in.nextInt();
		a = new int[n][30];
		
		for(int i=0;i<n;i++) {
			char[] s = in.next().toCharArray();
			for(char c:s)
				a[i][c-'a']++;
		}
		
		if(ch.length<8) {
			System.out.println(0);
			return;
		}
		
		int i=0,j=0;
		for(j=0;j<8;j++)
			cnt[ch[j]-'a']++;
		getAns();
		while(j<ch.length) {
			cnt[ch[i++]-'a']--;
			cnt[ch[j++]-'a']++;
			getAns();
		}
		
		System.out.println(ans);
	}
	
	static int n,ans=0;
	static int[][] a;//记录每个密码的各种字母出现的次数
	static int[] cnt = new int[30];//记录当前的扫到的各种字母个数
	
	static void getAns() {
		for(int i=0;i<n;i++) {
			boolean flag = true;
			for(int j=0;j<26;j++)
				if(cnt[j]!=a[i][j]) {
					flag = false;
					break;
				}
			if(flag)
				ans++;
		}
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值