您的位置:首页 > 其它

hdu 5972 Regular Number (bitset优化匹配) 2016大连现场赛

2017-10-01 22:06 471 查看
解题思路:暴力匹配过程太慢,我们考虑怎么优化这个过程,画图分析的话,最显然的是我们对文本串第 i 个字符进行了多次重复匹配 ,而我们又不能列出所有的模式串,所以无法使用KMP算法。

所以考虑建立10个长度为1000的bitset,分别记录数字0-9会出现在模式串的第几位。

再建立一个长度为1000的bitset a, a[i] 表示从以当前文本串位置 j 为结尾的长度为 i  的子串能否和模式串匹配。

这个算法的重点就是利用了两个bitset 使用&操作复杂度可以加速为 len/64。并且避免了多次重复匹配。

AC代码:

/*
* @Author: wchhlbt
* @Last Modified time: 2017-10-01
*/
//#include <bits/stdc++.h>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <limits>
#include <climits>
#include <cstdio>

#define inf 0x3f3f3f3f
#define pb push_back
#define AA first
#define BB second
#define ONES(x) __builtin_popcount(x)
#define _ << " " <<
using namespace std;

typedef pair<int, int> P;
typedef long long ll ;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
const double eps =1e-8;
const int mod = 1000000007;
const double PI = acos(-1.0);
//inline int read(){ int num; scanf("%d",&num); return num;}
const int maxn = 5000007;

namespace fastIO
{
#define BUF_SIZE 5000000
//fread -> read
bool IOerror = 0;
inline char nc()
{
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend)
{
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1)
{
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch = nc()));
if(IOerror)
return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
inline int readstr(char* x)
{
char ch;
while(blank(ch = nc()));
if(IOerror) return -1;
int i =0;
for(i; ch>='0'&&ch<='9'; i++)
{
x[i] = ch;
ch = nc();
}
x[i] = '\0';
return i;
}
#undef BUF_SIZE
};
using namespace fastIO;

bitset<1007> s[15];
bitset<1007> a;

char str[maxn];

int main()
{
int n;
while(1){
read(n);
if(IOerror) break;
a.reset();
for(int i = 0; i<10; i++)
s[i].reset();
for(int i = 0; i<n; i++){
int cnt;
read(cnt);
for(int j = 0; j<cnt; j++){
int num; read(num);
s[num].set(i);
}
}

readstr(str);
//cout << str << endl;
int m = strlen(str);
for(int i = 0; i<m; i++){
a[0] = 1;
a &= s[str[i]-'0'];
if(a[n-1]==1){
char t = str[i+1];
str[i+1] = '\0';
puts(str+i-n+1);
str[i+1] = t;
}
a <<= 1;
}
//cout << "hello" << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: