Advertisement
Guest User

Untitled

a guest
Sep 4th, 2014
410
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.99 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <queue>
  5. #include <map>
  6. #include <cstring>
  7. #include <algorithm>
  8. #include <sstream>
  9. #include <set>
  10. using namespace std;
  11.  
  12. typedef vector<string> vs;
  13. typedef map<string, string> mss;
  14. typedef map<string, bool> msb;
  15. typedef queue<string> qs;
  16. typedef pair<int,int> ii;
  17. typedef set<int> si;
  18. typedef vector<si> vsi;
  19.  
  20. const int MAXS = 1001*1001;
  21. const int MAXC = 30;
  22. const int MAXL = 1001;
  23. const char lowestChar = 'A';
  24. const char highestChar = 'Z';
  25.  
  26. int f[MAXS], g[MAXS][MAXC];
  27. vsi out;
  28.  
  29. inline int buildMatchingMachine(const vector<string> &words) {
  30.     out = vsi(MAXS);
  31.     memset(f, -1, sizeof f);
  32.     memset(g, -1, sizeof g);
  33.    
  34.     int states = 1;
  35.        
  36.     for (int i = 0; i < words.size(); ++i) {
  37.         const string &keyword = words[i];
  38.         int currentState = 0;
  39.         for (int j = 0; j < keyword.size(); ++j) {
  40.             int c = keyword[j] - lowestChar;
  41.             if (g[currentState][c] == -1) {
  42.                 g[currentState][c] = states++;
  43.             }
  44.             currentState = g[currentState][c];
  45.         }
  46.         out[currentState].insert(i);
  47.     }
  48.    
  49.  
  50.     for (int c = 0; c < MAXC; ++c) {
  51.         if (g[0][c] == -1) {
  52.             g[0][c] = 0;
  53.         }
  54.     }
  55.  
  56.    
  57.     queue<int> q;
  58.     for (int c = 0; c <= highestChar - lowestChar; ++c) {
  59.  
  60.         if (g[0][c] != -1 and g[0][c] != 0) {
  61.             f[g[0][c]] = 0;
  62.             q.push(g[0][c]);
  63.         }
  64.     }
  65.     while (q.size()) {
  66.         int state = q.front();
  67.         q.pop();
  68.         for (int c = 0; c <= highestChar - lowestChar; ++c) {
  69.             if (g[state][c] != -1) {
  70.                 int failure = f[state];
  71.                 while (g[failure][c] == -1) {
  72.                     failure = f[failure];
  73.                 }
  74.                 failure = g[failure][c];
  75.                 f[g[state][c]] = failure;
  76.                 out[g[state][c]].insert(out[failure].begin(), out[failure].end());
  77.                 q.push(g[state][c]);
  78.             }
  79.         }
  80.     }
  81.  
  82.     return states;
  83. }
  84.  
  85. inline int findNextState(int currentState, char nextInput) {
  86.     int answer = currentState;
  87.     int c = nextInput - lowestChar;
  88.     while (g[answer][c] == -1) answer = f[answer];
  89.     return g[answer][c];
  90. }
  91.  
  92. inline int revdir(int d) { return (d+4)%8; }
  93.  
  94. int T, L, C, W, dir[2], currentState[2];
  95. string mat[MAXL]; vs keywords; mss res; mss revk; msb isrev;
  96. string word, aux;
  97. 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) };
  98.  
  99. inline void ahostep(int i, int j, int idx) {
  100.     currentState[idx] = findNextState(currentState[idx], mat[i][j]);
  101.  
  102.     for (si::iterator it = out[currentState[idx]].begin();
  103.          it != out[currentState[idx]].end(); ++it) {
  104.            ostringstream ss;
  105.            if (isrev[keywords[*it]]) {
  106.                 ss << i << " " << j << " " << ((char)('A'+revdir(dir[idx]))) << "\n";
  107.                 res[revk[keywords[*it]]] = ss.str();
  108.            } else {
  109.                 int size = keywords[*it].size(),
  110.                     di = ddir[dir[idx]].first ? (ddir[dir[idx]].first*(size-1)) : 0,
  111.                     dj = ddir[dir[idx]].second ? (ddir[dir[idx]].second*(size-1)) : 0;
  112.                 ss << (i-di) << " " << (j-dj) << " " << ((char)('A'+dir[idx])) << "\n";
  113.                 res[keywords[*it]] = ss.str();
  114.            }
  115.     }
  116. }
  117.  
  118. int main(){
  119.     ios_base::sync_with_stdio(false);
  120.     cin >> T;
  121.     out.reserve(MAXS);
  122.  
  123.     while (T--) {
  124.         keywords.clear(); res.clear(); isrev.clear(); revk.clear();
  125.         qs resq;
  126.  
  127.         cin >> L >> C >> W;
  128.         for (int i=0; i<L; i++)
  129.             cin >> mat[i];
  130.  
  131.         for (int i=0; i<W; i++) {
  132.             cin >> word;
  133.  
  134.             keywords.push_back(word);
  135.             resq.push(word);
  136.             isrev[word] = false;
  137.             aux = word;
  138.  
  139.             reverse(word.begin(), word.end());
  140.  
  141.             keywords.push_back(word);
  142.             isrev[word] = true;
  143.             revk[word] = aux;
  144.            
  145.         }
  146.  
  147.         buildMatchingMachine(keywords);
  148.  
  149.         dir[0] = 3; dir[1] = 1;
  150.         for (int slice=0; slice < (L+C-1); ++slice) {
  151.             currentState[0] = 0; currentState[1] = 0;
  152.             int z1 = slice < C ? 0 : slice - C + 1;
  153.             int z2 = slice < L ? 0 : slice - L + 1;
  154.             for (int j = slice - z2; j >= z1; --j) {
  155.                 ahostep(L-j-1, slice-j, 0);
  156.                 ahostep(j, slice-j, 1);
  157.             }
  158.         }
  159.  
  160.         dir[0] = 2; dir[1] = 4;
  161.         for (int i=0; i<max(L,C); i++) {
  162.             currentState[0] = 0; currentState[1] = 0;
  163.             for (int j=0; j<max(L,C); j++) {
  164.                 if (i < L && j < C)
  165.                     ahostep(i,j,0);
  166.                 if (j < L && i < C)
  167.                     ahostep(j,i,1);
  168.             }
  169.         }
  170.  
  171.  
  172.         while (!resq.empty()) {
  173.             if (res.count(resq.front())) cout << res[resq.front()];
  174.             resq.pop();
  175.         }
  176.         if (T) cout << "\n";
  177.     }  
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement