BNUOJ 34990 Justice String

Justice String

Time Limit: 2000ms

Memory Limit: 65536KB

64-bit integer IO format: %lld      Java class name: Main

Given two strings A and B, your task is to find a substring of A called justice string, which has the same length as B, and only has at most two characters different from B.

Input

The first line of the input contains a single integer T, which is the number of test cases.

For each test case, the first line is string A, and the second is string B.

Both string A and B contain lowercase English letters from a to z only. And the length of these two strings is between 1 and 100000, inclusive.

Output

For each case, first output the case number as "Case #x: ", and x is the case number. Then output a number indicating the start position of substring C in A, position is counted from 0. If there is no such substring C, output -1.

And if there are multiple solutions, output the smallest one.

Sample Input

3
aaabcd
abee
aaaaaa
aaaaa
aaaaaa
aabbb

Sample Output

Case #1: 2
Case #2: 0
Case #3: -1

Source

2014 ACM-ICPC Beijing Invitational Programming Contest

解题:Hash+二分

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 100100;
18 char sa[maxn],sb[maxn];
19 unsigned LL Ha[maxn],Hb[maxn],p = 131;
20 int len1,len2;
21 unsigned LL pp[maxn];
22 int calc(int a,int b){
23     int high = min(len1 - a,len2 - b),low = 0,mid,ans = 0;
24     while(low <= high){
25         mid = (low + high)>>1;
26         unsigned LL v1 = Ha[a] - Ha[a+mid]*pp[mid];
27         unsigned LL v2 = Hb[b] - Hb[b+mid]*pp[mid];
28         if(v1 == v2){
29             ans = mid;
30             low = mid + 1;
31         }else high = mid - 1;
32     }
33     return ans;
34 }
35 int main() {
36     int T,cs = 1;
37     pp[0] = 1;
38     for(int i = 1; i < maxn; ++i) pp[i] = pp[i-1]*p;
39     scanf("%d",&T);
40     while(T--){
41         scanf("%s %s",sa,sb);
42         len1 = strlen(sa);
43         len2 = strlen(sb);
44         Ha[len1] = 0;
45         Hb[len2] = 0;
46         for(int i = len1-1; i >= 0; --i) Ha[i] = Ha[i+1]*p + sa[i];
47         for(int i = len2-1; i >= 0; --i) Hb[i] = Hb[i+1]*p + sb[i];
48         int ans = -1;
49         for(int i = 0; i <= len1 - len2; ++i){
50             int sum = 0,a = i,b = 0,tmp = 0;
51             tmp = calc(a,b);
52             if(tmp >= len2-2){
53                 ans = i;
54                 break;
55             }
56             sum += tmp;
57             a += tmp+1;
58             b += tmp+1;
59             tmp = calc(a,b);
60             sum += tmp;
61             if(sum >= len2-2){
62                 ans = i;
63                 break;
64             }
65             a += tmp+1;
66             b += tmp+1;
67             tmp = calc(a,b);
68             sum += tmp;
69             if(sum >= len2-2){
70                 ans = i;
71                 break;
72             }
73         }
74         printf("Case #%d: %d\n",cs++,ans);
75     }
76     return 0;
77 }

时间: 2024-08-11 03:27:41

BNUOJ 34990 Justice String的相关文章

BNU 34990 Justice String (hash+二分求LCP)

思路:枚举第一个字符串的位置,然后枚举最长公共前缀的长度,时间即会下降-- #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<

BNUOJ 34985 Elegant String 2014北京邀请赛E题 动态规划 矩阵快速幂

Elegant String Time Limit: 1000msMemory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,-, k

BNUOJ 34985 Elegant String 2014北京邀请赛E题 矩阵快速幂

题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 题目大意:问n长度的串用0~k的数字去填,有多少个串保证任意子串中不包含0~k的某一个全排列 邀请赛上A的较多的一道题,比赛的时候死活想不出,回来之后突然就想通了,简直..... = =! 解题思路: 对于所有串我们都只考虑末尾最多有多少位能构成全排列的一部分(用l来表示),即最多有多少位不重复的数字出现,将问题转化为求末尾最多有k位能构成全排列的串的总数量 假设k为5,有一个

bnuoj 34990(后缀数组 或 hash+二分)

后缀数组倍增算法超时,听说用3DC可以勉强过,不愿写了,直接用hash+二分求出log(n)的时间查询两个字符串之间的任意两个位置的最长前缀. 我自己在想hash的时候一直在考虑hash成数值时MOD取多大,如果取10^18的话,那么两数相乘个就超LL了,但是取10^9的话又怕出现重复的可能大.后面才发现自己是sb,如果用unsigned long long 如果有溢出或者为负数是直接变成对(1<<64)取模了. 也就是无符号长整形运算自动帮你取模了.所以可以放心用hash Justice S

hihocoder 1084 扩展KMP &amp;&amp; 2014 北京邀请赛 Justice String

hihocoder 1084 : http://hihocoder.com/problemset/problem/1084 北京邀请赛 Just  String http://www.bnuoj.com/v3/problem_show.php?pid=34990 两道题同样的做法,题目基本内容是找到A的字串中和B串长度一样,且不同的字符个数不超过k个的置. 以hihocoder 1084为例, 是求有多少个A的字串的,与B串长度一样,且不同的字符个数不超过k. 分析:预处理hash,然后对每个字

bnuoj 34985 Elegant String

题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,…, k". Let function(n, k) be the number of elegant s

BNUOJ 34990 北京邀请赛最后一题

思路:这题看了题解说是后缀数组做的,然后自己就偿试了一下,唉--没想到不管是不管是倍增算法的后缀还是DC3算法的后缀都T了,实在无计可施了,可能只有哗然可以过了.不过比赛那天题解说是没有卡后缀的.只是比赛那天自己还不会后缀数组,所以这题自己根本就没有看到.因为后缀自己练得还比较少,这题正好用RMQ求任意两个后缀之间的最长公共前缀,所以自己就拿这题练手了,虽然T了,但是倍增的算法和DC3的算法都贴上来吧,以配以后可能用得到. 倍增算法的代码: #pragma comment(linker, "/S

bunoj 34990(hash)

传送门:Justice String 题意:有两个串A,B,问是否存在A的一个子串S,S和B的长度相等,最多有2个字符不同.如果有多个,输出其实下标最小S的下标,没有输出-1. 分析:从A每个位置开始找最长公共前缀,如果最长公共前缀长度不大于lenb,继续从下一次位置开始找,至多找两次,如果一直找不到就算不存在. #include <cstdio> #include <cstring> #include <string> #include <queue> #

2014 北京邀请赛ABDHJ题解

A. A Matrix 点击打开链接 构造,结论是从第一行开始往下产生一条曲线,使得这条区间最长且从上到下递减, #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <stdio.h> #include <vector> #include <set> using namespace std; #defi