SPOJ WPUZZLES (POJ 1204) 413.Word Puzzles AC自动机
来源:互联网 发布:ionic lab mac 下载 编辑:程序博客网 时间:2024/05/20 04:28
POJ 1204 和SPOJ WPUZZLES一样..换了一下输入输出格式而已..
题目大意:
就是现在有一个游戏,给你一个L*C的字符块,只包含大写英文字母,现在你要在这个块中找到给出的所有的英语单词的位置和摆放方向。
其中要找的单词在块中只出现一次,(实际上多个要找的块不会重合,这个游戏就是这样...)
对于每个要找的字符串,输出其在块中起始位置的坐标和方向,方向只有8种,并且单词摆放不会拐弯..就是一条线摆放
大致思路:
其实就是个简单的模板题...首先将所有要找的字符串建立AC自动机,标号其结尾点,然后枚举矩阵的所有串,当然起点和重点都是边界,实际上要枚举的串并不多,找到串的时候利用串的长度和方向就可以很快算出起点位置,最后输出就可以了...
代码如下:
Result : Accepted Memory : 113664 KB Time : 320 ms
/* * Author: Gatevin * Created Time: 2014/11/26 15:30:39 * File Name: Kagome.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;const double eps(1e-8);typedef long long lint;int t;int R, C, W;char m[1001][1001];char s[1001];int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1}; int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};struct Ans{ int x, y, dir;};Ans ans[1001];int len[1001];int next[1000001][26], fail[1000001], end[1000001];struct Trie{ int L, root; int newnode() { for(int i = 0; i < 26; i++) next[L][i] = -1; end[L++] = -1;//end[i] = -1表示点i不是字符串结尾点 return L - 1; } void init() { L = 0; root = newnode(); return; } void insert(char* in, int id) { int now = root; for(; *in; in++) { if(next[now][*in - 'A'] == -1) next[now][*in - 'A'] = newnode(); now = next[now][*in - 'A']; } end[now] = id; return; } void build() { fail[root] = root; queue <int> Q; Q.push(root); while(!Q.empty()) { int now = Q.front(); Q.pop(); for(int i = 0; i < 26; i++) if(next[now][i] == -1) next[now][i] = now == root ? root : next[fail[now]][i]; else { fail[next[now][i]] = now == root ? root : next[fail[now]][i]; Q.push(next[now][i]); } } return; } void find(int x, int y, int dir) { int now = root; while(x >= 0 && y >= 0 && x < R && y < C) { now = next[now][m[x][y] - 'A']; /* * 由于是字符块游戏,不会出现两块有重叠部分出现的情况 * 所以这里可以不用while(tmp != root) tmp = fail[tmp];这一段 */ if(end[now] >= 0)//找到字符串了 { ans[end[now]].x = x - (len[end[now]] - 1)*dx[dir];//计算起点位置 ans[end[now]].y = y - (len[end[now]] - 1)*dy[dir]; ans[end[now]].dir = dir; } x += dx[dir]; y += dy[dir]; } return; }};Trie AC;int main(){ scanf("%d", &t); while(t--) { AC.init(); scanf("%d %d %d", &R, &C, &W); for(int i = 0; i < R; i++) scanf("%s", m[i]); for(int i = 0; i < W; i++) { scanf("%s", s); AC.insert(s, i); len[i] = strlen(s); } AC.build(); /* * 将模板串建立AC自动机之后枚举矩形中所有的串就可以了 */ for(int i = 0; i < R; i++) { AC.find(i, 0, 1); AC.find(i, 0, 2); AC.find(i, 0, 3); //左边起点,方向为右上,右,右下的字符串 AC.find(i, C - 1, 5); AC.find(i, C - 1, 6); AC.find(i, C - 1, 7); //右边起点,方向为左上,左,左下的字符串 } for(int i = 0; i < C; i++) { AC.find(0, i, 3); AC.find(0, i, 4); AC.find(0, i, 5); //上边为起点,方向右下,下,左下 AC.find(R - 1, i, 7); AC.find(R - 1, i, 0); AC.find(R - 1, i, 1); //下边为起点,方向左上,上,右上 } for(int i = 0; i < W; i++) printf("%d %d %c\n", ans[i].x, ans[i].y, ans[i].dir + 'A'); if(t) printf("\n"); } return 0;}
0 0
- SPOJ WPUZZLES (POJ 1204) 413.Word Puzzles AC自动机
- poj 1204:Word Puzzles(AC自动机)
- poj 1204 Word Puzzles AC自动机
- POJ 1204 Word Puzzles AC自动机
- poj - 1204 - Word Puzzles(AC自动机)
- poj 1204 Word Puzzles (AC自动机)
- POJ 1204 Word Puzzles AC自动机题解
- poj 1204 Word Puzzles (ac自动机)
- POJ 1204 Word Puzzles (AC自动机)
- POJ 1204 Word Puzzles AC自动机 -
- POJ 1204 Word Puzzles ac自动机
- POJ 1204 Word Puzzles(AC自动机)
- [POJ 1204]Word Puzzles(Trie树暴搜&AC自动机)
- POJ1204 Word Puzzles AC自动机
- POJ1204--Word Puzzles--AC自动机
- 【POJ1204】Word Puzzles-AC自动机
- POJ 题目1204 Word Puzzles(AC自动机,多个方向查询)
- 【POJ1204】Word Puzzles——AC自动机
- [转载]实句柄和伪句柄
- Entity Framework4.0 (三)概述(EF4 的Code First方法)
- HDU 4433 locker(三维dp)
- dbcp配置解释
- Linux负载均衡软件LVS之一(概念篇)
- SPOJ WPUZZLES (POJ 1204) 413.Word Puzzles AC自动机
- 毕业一年多了
- uva11107 - Life Forms 后缀数组
- java底层加载机制
- Java垃圾回收机制
- final关键字
- VB.net程序System.BadImageFormatException: 试图加载格式不正确的程序
- 判断Map的value值是否相等,相等则将key值组成字符串
- u-boot-2014.10移植第23天----nand flash启动(一)