Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <vector>
- #include <queue>
- #include <map>
- #include <cstring>
- #include <algorithm>
- #include <sstream>
- #include <set>
- using namespace std;
- typedef vector<string> vs;
- typedef map<string, string> mss;
- typedef map<string, bool> msb;
- typedef queue<string> qs;
- typedef pair<int,int> ii;
- typedef set<int> si;
- typedef vector<si> vsi;
- const int MAXS = 1001*1001;
- const int MAXC = 30;
- const int MAXL = 1001;
- const char lowestChar = 'A';
- const char highestChar = 'Z';
- int f[MAXS], g[MAXS][MAXC];
- vsi out;
- inline int buildMatchingMachine(const vector<string> &words) {
- out = vsi(MAXS);
- memset(f, -1, sizeof f);
- memset(g, -1, sizeof g);
- int states = 1;
- for (int i = 0; i < words.size(); ++i) {
- const string &keyword = words[i];
- int currentState = 0;
- for (int j = 0; j < keyword.size(); ++j) {
- int c = keyword[j] - lowestChar;
- if (g[currentState][c] == -1) {
- g[currentState][c] = states++;
- }
- currentState = g[currentState][c];
- }
- out[currentState].insert(i);
- }
- for (int c = 0; c < MAXC; ++c) {
- if (g[0][c] == -1) {
- g[0][c] = 0;
- }
- }
- queue<int> q;
- for (int c = 0; c <= highestChar - lowestChar; ++c) {
- if (g[0][c] != -1 and g[0][c] != 0) {
- f[g[0][c]] = 0;
- q.push(g[0][c]);
- }
- }
- while (q.size()) {
- int state = q.front();
- q.pop();
- for (int c = 0; c <= highestChar - lowestChar; ++c) {
- if (g[state][c] != -1) {
- int failure = f[state];
- while (g[failure][c] == -1) {
- failure = f[failure];
- }
- failure = g[failure][c];
- f[g[state][c]] = failure;
- out[g[state][c]].insert(out[failure].begin(), out[failure].end());
- q.push(g[state][c]);
- }
- }
- }
- return states;
- }
- inline int findNextState(int currentState, char nextInput) {
- int answer = currentState;
- int c = nextInput - lowestChar;
- while (g[answer][c] == -1) answer = f[answer];
- return g[answer][c];
- }
- inline int revdir(int d) { return (d+4)%8; }
- int T, L, C, W, dir[2], currentState[2];
- string mat[MAXL]; vs keywords; mss res; mss revk; msb isrev;
- string word, aux;
- ii ddir[] = { ii(-1,0), ii(-1,1), ii(0,1), ii(1,1), ii(1,0), ii(1,-1), ii(0,-1), ii(-1,-1) };
- inline void ahostep(int i, int j, int idx) {
- currentState[idx] = findNextState(currentState[idx], mat[i][j]);
- for (si::iterator it = out[currentState[idx]].begin();
- it != out[currentState[idx]].end(); ++it) {
- ostringstream ss;
- if (isrev[keywords[*it]]) {
- ss << i << " " << j << " " << ((char)('A'+revdir(dir[idx]))) << "\n";
- res[revk[keywords[*it]]] = ss.str();
- } else {
- int size = keywords[*it].size(),
- di = ddir[dir[idx]].first ? (ddir[dir[idx]].first*(size-1)) : 0,
- dj = ddir[dir[idx]].second ? (ddir[dir[idx]].second*(size-1)) : 0;
- ss << (i-di) << " " << (j-dj) << " " << ((char)('A'+dir[idx])) << "\n";
- res[keywords[*it]] = ss.str();
- }
- }
- }
- int main(){
- ios_base::sync_with_stdio(false);
- cin >> T;
- out.reserve(MAXS);
- while (T--) {
- keywords.clear(); res.clear(); isrev.clear(); revk.clear();
- qs resq;
- cin >> L >> C >> W;
- for (int i=0; i<L; i++)
- cin >> mat[i];
- for (int i=0; i<W; i++) {
- cin >> word;
- keywords.push_back(word);
- resq.push(word);
- isrev[word] = false;
- aux = word;
- reverse(word.begin(), word.end());
- keywords.push_back(word);
- isrev[word] = true;
- revk[word] = aux;
- }
- buildMatchingMachine(keywords);
- dir[0] = 3; dir[1] = 1;
- for (int slice=0; slice < (L+C-1); ++slice) {
- currentState[0] = 0; currentState[1] = 0;
- int z1 = slice < C ? 0 : slice - C + 1;
- int z2 = slice < L ? 0 : slice - L + 1;
- for (int j = slice - z2; j >= z1; --j) {
- ahostep(L-j-1, slice-j, 0);
- ahostep(j, slice-j, 1);
- }
- }
- dir[0] = 2; dir[1] = 4;
- for (int i=0; i<max(L,C); i++) {
- currentState[0] = 0; currentState[1] = 0;
- for (int j=0; j<max(L,C); j++) {
- if (i < L && j < C)
- ahostep(i,j,0);
- if (j < L && i < C)
- ahostep(j,i,1);
- }
- }
- while (!resq.empty()) {
- if (res.count(resq.front())) cout << res[resq.front()];
- resq.pop();
- }
- if (T) cout << "\n";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement