【HDOJ】1857 Word Puzzle
trie树。以puzzle做trie树内存不够,从puzzle中直接找串应该会TLE。其实可以将查询组成trie树,离线做。
扫描puzzle时注意仅三个方向即可。
1 /* 1857 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int maxr = 505; 43 const int maxc = 505; 44 const int maxn = 2e5+5; 45 const int maxm = 1e4+5; 46 char s[maxr][maxc], ss[maxc]; 47 int X[maxn], Y[maxn]; 48 int nxt[maxn][26]; 49 int P[maxm]; 50 int l = 1; 51 int wn = 0; 52 int n, m; 53 54 void init() { 55 memset(X, -1, sizeof(X)); 56 memset(Y, -1, sizeof(Y)); 57 } 58 59 inline int newNode() { 60 return l++; 61 } 62 63 void Insert(char *s) { 64 int i = 0, id; 65 int p = 0, q; 66 67 while (s[i]) { 68 id = s[i] - 'A'; 69 q = nxt[p][id]; 70 if (!q) 71 q = nxt[p][id] = newNode(); 72 p = q; 73 ++i; 74 } 75 P[wn++] = p; 76 } 77 78 void Find(char *s, int x, int y) { 79 int i = 0, id; 80 int p = 0; 81 82 while (s[i]) { 83 id = s[i] - 'A'; 84 p = nxt[p][id]; 85 if (!p) 86 return ; 87 if (X[p]<0 || x<X[p] || (x==X[p] && y<Y[p])) { 88 X[p] = x; 89 Y[p] = y; 90 } 91 ++i; 92 } 93 } 94 95 void solve() { 96 // horizontal 97 rep(i, 0, n) { 98 strcpy(ss, s[i]); 99 rep(j, 0, m) 100 Find(ss+j, i, j); 101 } 102 103 104 // vertical 105 rep(j, 0, m) { 106 rep(i, 0, n) 107 ss[i] = s[i][j]; 108 ss[n] = '\0'; 109 rep(i, 0, n) 110 Find(ss+i, i, j); 111 } 112 113 114 // diagonal 115 int x, y, l; 116 117 rep(i, 0, n) { 118 x = i; 119 y = 0; 120 l = 0; 121 while (x<n && y<m) { 122 ss[l++] = s[x][y]; 123 ++x; 124 ++y; 125 } 126 ss[l] = '\0'; 127 rep(k, 0, l) 128 Find(ss+k, i+k, k); 129 } 130 131 rep(j, 1, m) { 132 x = 0; 133 y = j; 134 l = 0; 135 while (x<n && y<m) { 136 ss[l++] = s[x][y]; 137 ++x; 138 ++y; 139 } 140 ss[l] = '\0'; 141 rep(k, 0, l) 142 Find(ss+k, k, j+k); 143 } 144 145 } 146 147 int main() { 148 ios::sync_with_stdio(false); 149 #ifndef ONLINE_JUDGE 150 freopen("data.in", "r", stdin); 151 freopen("data.out", "w", stdout); 152 #endif 153 154 init(); 155 scanf("%d %d", &n, &m); 156 rep(i, 0, n) 157 scanf("%s", s[i]); 158 getchar(); 159 getchar(); 160 while (scanf("%s", ss)!=EOF && ss[0]!='-') { 161 Insert(ss); 162 } 163 164 solve(); 165 166 int p; 167 rep(i, 0, wn) { 168 p = P[i]; 169 printf("%d %d\n", X[p], Y[p]); 170 } 171 172 #ifndef ONLINE_JUDGE 173 printf("time = %d.\n", (int)clock()); 174 #endif 175 176 return 0; 177 }