Regular Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1644 Accepted Submission(s): 445
Problem Description
Using regular expression to define a numeric string is a very common thing. Generally, use the shape as follows:
(0|9|7) (5|6) (2) (4|5)
Above regular expression matches 4 digits:The first is one of 0,9 and 7. The second is one of 5 and 6. The third is 2. And the fourth is one of 4 and 5. The above regular expression can be successfully matched to 0525, but it cannot be matched to 9634.
Now,giving you a regular expression like the above formula,and a long string of numbers,please find out all the substrings of this long string that can be matched to the regular expression.
(0|9|7) (5|6) (2) (4|5)
Above regular expression matches 4 digits:The first is one of 0,9 and 7. The second is one of 5 and 6. The third is 2. And the fourth is one of 4 and 5. The above regular expression can be successfully matched to 0525, but it cannot be matched to 9634.
Now,giving you a regular expression like the above formula,and a long string of numbers,please find out all the substrings of this long string that can be matched to the regular expression.
Input
It contains a set of test data.The first line is a positive integer N (1 ≤ N ≤ 1000),on behalf of the regular representation of the N bit string.In the next N lines,the first integer of the i-th line is
ai(1≤ai≤10)
,representing that the i-th position of regular expression has
ai
numbers to be selected.Next there are
ai
numeric characters. In the last line,there is a numeric string.The length of the string is not more than 5 * 10^6.
Output
Output all substrings that can be matched by the regular expression. Each substring occupies one line
Sample Input
4 3 0 9 7 2 5 7 2 2 5 2 4 5 09755420524
Sample Output
9755 7554 0524
Source
学会使用bitset。
一共就九个数字。所以可以将每个数字对应的数组的出现过的位置置为1,没出现过置为0.
比如b[5]对应的就是0111
如果ans[k]=1表示从这个位置开始往前的长度为k+1的串可以和子串的前缀进行匹配。
把低位置一,这样就保证了只有匹配,这个1才能往下传递,所以一直传递到第n-1位,这样代表都匹配了。
当ans[n-1]的时候,说明从i-n+1位置开始的母串可以和子串匹配,这个时候输出
然后就是数据很大得使用gets puts 才不超时。
#include<bitset>
#include<cstdio>
using namespace std;
const int maxn=5*1e6+5;
bitset<1005>b[11];
bitset<1005>ans;
char s[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<10;i++)
b[i].reset(); //将b[i]中所有二进制位置0
for(int i=0;i<n;i++)
{
int num;
scanf("%d",&num);
for(int j=0;j<num;j++)
{
int tmp;
scanf("%d",&tmp);
b[tmp].set(i); //把b[tmp]的i位二进制置为1
}
}
// getchar();
scanf(" %s",s);
ans.reset();
for(int i=0;s[i]!='\0';i++)
{
ans=ans<<1;
ans.set(0);
ans=ans&b[s[i]-'0'];
if(ans[n-1]==1) //注意这种输出方式
{
char c=s[i+1];
s[i+1]='\0';
puts(s+i-n+1);
s[i+1]=c;
}
}
}
return 0;
}