HDU 5972 Regular Number(字符串shift-and算法)

题目链接  HDU5972

2016 ACM/ICPC 大连区域赛 B题

我们预处理出b[i][j],b[i][j] = 1的意义是数字i可以放在第j位。

然后就开始这个匹配的过程。

假设字符串第一位下标从1开始

我们每一次处理的子串为s[i - n + 1], s[i  - n + 2], s[i - n + 3], ..., s[i]

ans[k] = 1的含义是 s[i - k + 1], s[i - k + 2], s[i - k + 3], ..., s[i]这k位可以与t[1], t[2], t[3], t[4],..., t[k]匹配

所以当ans[n] = 1的时候我们就可以输出当前这个子串

其中t[]表示输入的那张表。

每次处理的时候,我们先把ans往右移动一位,然后把ans[1]设成1.

但是这样是不够的,这相当于把原来那个子串的最前面那位去掉了,我们还要加入最高位。

所以这个时候的ans还要和b[num]进行与运算。(num为新的最高位)

于是这样一位位处理过去就可以了。

用bitset优化,输出的时候用字符串输出,不然会超时。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

typedef long long LL;

const int N = 5000010;
const int M = 1002;

bitset <M> b[11];
int n;
char s[N];

int main(){

	while (~scanf("%d", &n)){
		rep(i, 0, 9) b[i].reset();
		rep(i, 0, n - 1){
			int x;
			scanf("%d", &x);
			rep(j, 1, x){
				int y;
				scanf("%d", &y);
				b[y][i] = 1;
			}
		}

		scanf("%s", s);
		bitset <M> ans;
		for (int i = 0; s[i]; ++i){
			ans <<= 1;
			ans[0] = 1;
			ans &= b[s[i] - ‘0‘];
			if (ans[n - 1]){
				char tmp = s[i + 1];
			       	s[i + 1] = ‘\0‘;
				puts(s + i - n + 1);
				s[i + 1] = tmp;
			}
		}
	}
	return 0;
}
时间: 2024-08-03 11:08:47

HDU 5972 Regular Number(字符串shift-and算法)的相关文章

hdu 5972 Regular Number

Regular Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 620    Accepted Submission(s): 134 Problem Description Using regular expression to define a numeric string is a very common thing.

HDU 5972 Regular Number(ShiftAnd+读入优化)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5972 [题目大意] 给出一个字符串,找出其中所有的符合特定模式的子串位置,符合特定模式是指,该子串的长度为n,并且第i个字符需要在给定的字符集合Si中 [题解] 利用ShiftAnd匹配算法. bt[i]表示字符i允许在哪些位置上出现,我们将匹配成功的位置保存在dp中,那么就可以用dp[i]=dp[i-1]<<1&bt[s[i]]来更新答案了 利用滚动数组和bitset可以来优化这样的

HDU - 1711 A - Number Sequence(kmp

HDU - 1711 A - Number Sequence Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[

hdu 4937 Lucky Number ( 进制转换+枚举 )

题意: 有一个数n,问有多少个进制x(基数)使得n转换为x进制后的数字中只有3.4.5.6四个数. 算法: 对于只有一位数的情况,显然3.4.5.6都应该输出-1. 如果有2位数,假设这2位中高位为a,低位为b,进制为base,则 n = a * base + b,解一元一次方程即可. 如果有3位数,假设这3为从高到低分别为a.b.c,进制为base,则 n = a * base * base + b * base + c,即一元二次方程即可. 如果位数>= 4,可以暴力枚举进制数.base>

hdu 5787 K-wolf Number 数位dp

数位DP 神模板 详解 为了方便自己参看,我把代码复制过来吧 // pos = 当前处理的位置(一般从高位到低位) // pre = 上一个位的数字(更高的那一位) // status = 要达到的状态,如果为1则可以认为找到了答案,到时候用来返回, // 给计数器+1. // limit = 是否受限,也即当前处理这位能否随便取值.如567,当前处理6这位, // 如果前面取的是4,则当前这位可以取0-9.如果前面取的5,那么当前 // 这位就不能随便取,不然会超出这个数的范围,所以如果前面取

HDU 4937 Lucky Number (数学,进制转换)

题目 参考自博客:http://blog.csdn.net/a601025382s/article/details/38517783 //string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last); //把[first0,last0)之间的部分替换成[first,last)之间的字符串 /* 题意: 我们将3,4,5,6认为是幸运数字.给定一个十进制数n. 现在可以讲起任意转

hdu 1068 Girls and Boys(匈牙利算法求最大独立集)

Girls and Boys Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7044    Accepted Submission(s): 3178 Problem Description the second year of the university somebody started a study on the roman

hdu 4937 Lucky Number

虽然算法清晰的不能再清晰,但是实现总是边角料错这错那. 题目大意: 给出n,找出一些进制,使得n在该进制下仅为3,4,5,6表示 解题思路: 首先,4-10000进制直接枚举计算出每一位 此外,最多只有3位,因为10000进制以上且小于1e12,最多3位,直接枚举每一位计算进制N即可 注意:如果类似我用二分或者直接求二次根式,要开个map储存已经计算出来的N进行判重,虽然数据比较弱可以不用判.最多4^3个吧,多了可能会重. #include <cstdio> #include <cstr

hdu 2586 LCA模板题(离线算法)

http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B&quo