ZOJ 3430 Detect the Virus 【AC自动机+解码】
生活随笔
收集整理的這篇文章主要介紹了
ZOJ 3430 Detect the Virus 【AC自动机+解码】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
解碼的那些事兒,不多說。
注意解碼后的結果各種情況都有,用整數數組存儲,char數組會超char類型的范圍(這個事最蛋疼的啊)建立自動機的時候不能用0來判斷結束。
?
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> #include <string> #include <iostream> using namespace std; vector<int> ans;struct AC_Automata {#define N 60010#define M 256int ch[N][M], sz;int val[N], last[N], f[N], cc[N];void clear() {sz = 1;memset(ch[0], 0, sizeof(ch[0]));}void insert(int s[], int l, int v) {int u = 0;for (int i=0; i<l; i++) {int c = s[i];if (!ch[u][c]) {memset(ch[sz], 0, sizeof(ch[sz]));val[sz] = 0;ch[u][c] = sz++;}u = ch[u][c];}val[u] = v;}void build() {queue<int> q;f[0] = 0;for (int c=0; c<M; c++) {int u = ch[0][c];if (u) { f[u] = last[u] = 0; q.push(u); }}while (!q.empty()) {int r = q.front(); q.pop();for (int c=0; c<M; c++) {int u = ch[r][c];if (!u) { ch[r][c] = ch[f[r]][c]; continue; }q.push(u);f[u] = ch[f[r]][c];last[u] = val[f[u]] ? f[u] : last[f[u]];}}}void find(int s[], int l) {int j = 0;for (int i=0; i<l; i++) {int c = s[i];j = ch[j][c];if (val[j]) print(j);else if (last[j]) print(last[j]);}}void print(int j) {if (j) {ans.push_back(val[j]);print(last[j]);}} } ac; int get(char c) {if (c >= 'A' && c <= 'Z') return c-'A';if (c >= 'a' && c <= 'z') return c-'a'+26;if (c >= '0' && c <= '9') return c-'0'+ 52;if (c == '+') return 62;return 63; }int ss[30002]; int bit[30003*10];int decode(char str[]) {int top = 0;int a[10];for(int i=0; str[i]; i++) {if(str[i]!='='){int x = get(str[i]);for(int j=5;j>=0;j--){a[j] = x & 1;x >>= 1;}for (int j=0; j<6; j++) bit[top++] = a[j];}elsetop -= 2;}int x = 0;int tot = 0;for(int i=0;i<top;){x = 0;for(int j=0;j<8;j++)x = x<<1 | bit[i++];ss[tot++] = x;}return tot; }int main() { #ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin); #endifint n, m;char s[30023];while (scanf(" %d", &n) == 1) {ac.clear();for (int i=1; i<=n; i++) {scanf(" %s", s);int l = decode(s);ac.insert(ss, l, i);}ac.build();scanf(" %d", &m);while (m--) {ans.clear();scanf(" %s", s);int l = decode(s);ac.find(ss, l);sort(ans.begin(), ans.end());int cnt = unique(ans.begin(), ans.end()) - ans.begin();printf("%d\n", cnt);}puts("");}return 0; }?
?
總結
以上是生活随笔為你收集整理的ZOJ 3430 Detect the Virus 【AC自动机+解码】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dynamics CRM 2013 初体
- 下一篇: Cannot create a sess