您的位置:首页 > 编程语言 > Java开发

ACM POJ 1204 (Word Puzzles)

2014-01-19 22:53 399 查看
题目链接 http://poj.org/problem?id=1204

思路 将最后输入的字符串都存到trie中,然后遍历矩阵中的字符串,判断其是否在trie中

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.TreeSet;

public class Main {

public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
int[][] direction = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 },
{ 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 } };
while (scn.hasNext()) {
int lines = Integer.parseInt(scn.next());
int columns = Integer.parseInt(scn.next());
int wordsNumber = Integer.parseInt(scn.next());
char[][] matrix = new char[lines][columns];
for (int i = 0; i < lines; ++i) {
matrix[i] = scn.next().toCharArray();
}
Trie trie = new Trie();
for (int i = 0; i < wordsNumber; ++i) {
trie.insert(scn.next(), i);
}
trie.build();
TreeSet<NodeResult> set = new TreeSet<NodeResult>();
// 先考虑四个点,再考虑四条边
// 对于(0,0)点有2 3 4 三个方向
search(direction, matrix, lines, columns, 0, 0, 2, trie, set);
search(direction, matrix, lines, columns, 0, 0, 3, trie, set);
search(direction, matrix, lines, columns, 0, 0, 4, trie, set);
// 对于(0,columns-1)点有4 5 6 三个方向
search(direction, matrix, lines, columns, 0, columns - 1, 4, trie,
set);
search(direction, matrix, lines, columns, 0, columns - 1, 5, trie,
set);
search(direction, matrix, lines, columns, 0, columns - 1, 6, trie,
set);
// 对于(lines-1,0)点有0 1 2 三个方向
search(direction, matrix, lines, columns, lines - 1, 0, 0, trie,
set);
search(direction, matrix, lines, columns, lines - 1, 0, 1, trie,
set);
search(direction, matrix, lines, columns, lines - 1, 0, 2, trie,
set);
// 对于(lines,columns)点有6 7 0 三个方向
search(direction, matrix, lines, columns, lines - 1, columns - 1,
6, trie, set);
search(direction, matrix, lines, columns, lines - 1, columns - 1,
7, trie, set);
search(direction, matrix, lines, columns, lines - 1, columns - 1,
0, trie, set);
// 对于上边,有3 4 5 三个方向
for (int j = 1; j < columns - 1 && set.size() != wordsNumber; ++j) {
search(direction, matrix, lines, columns, 0, j, 3, trie, set);
search(direction, matrix, lines, columns, 0, j, 4, trie, set);
search(direction, matrix, lines, columns, 0, j, 5, trie, set);
}
// 对于左边,有1 2 3 三个方向
for (int i = 1; i < lines - 1 && set.size() != wordsNumber; ++i) {
search(direction, matrix, lines, columns, i, 0, 1, trie, set);
search(direction, matrix, lines, columns, i, 0, 2, trie, set);
search(direction, matrix, lines, columns, i, 0, 3, trie, set);
}
// 对于右边,有5 6 7 三个方向
for (int i = 1; i < lines - 1 && set.size() != wordsNumber; ++i) {
search(direction, matrix, lines, columns, i, columns - 1, 5,
trie, set);
search(direction, matrix, lines, columns, i, columns - 1, 6,
trie, set);
search(direction, matrix, lines, columns, i, columns - 1, 7,
trie, set);
}
// 对于下边,有 7 0 1 三个方向
for (int j = 1; j < columns - 1 && set.size() != wordsNumber; ++j) {
search(direction, matrix, lines, columns, lines - 1, j, 7,
trie, set);
search(direction, matrix, lines, columns, lines - 1, j, 0,
trie, set);
search(direction, matrix, lines, columns, lines - 1, j, 1,
trie, set);
}
// 输出结果
Iterator<NodeResult> it = set.iterator();
while (it.hasNext()) {
NodeResult nodeResult = it.next();
System.out.println(nodeResult.getX() + " " + nodeResult.getY()
+ " " + nodeResult.getDirection());
}
}
scn.close();
}

public static void search(int[][] direction, char[][] matrix, int lines,
int columns, int startX, int startY, int k, Trie trie,
TreeSet<NodeResult> set) {
ArrayList<Node> list = trie.search(getString(matrix, lines, columns,
startX, startY, direction[k][0], direction[k][1]));
for (int i = 0; i < list.size(); ++i) {
Node node = list.get(i);
int x = startX, y = startY;
for (int j = 0; j < node.getStart(); ++j) {
x += direction[k][0];
y += direction[k][1];
}
NodeResult nodeResult = new NodeResult(x, y, (char) ('A' + k),
node.getNumber());
set.add(nodeResult);
}
}

public static String getString(char[][] matrix, int lines, int columns,
int x, int y, int dirX, int dirY) {
StringBuilder sbd = new StringBuilder();
while (true) {
if (0 > x || x >= lines || 0 > y || y >= columns) {
break;
}
sbd.append(matrix[x][y]);
x += dirX;
y += dirY;
}
return sbd.toString();
}

}

class Trie {

private Node root;

public Trie() {
root = new Node(new Node[26], null, -1);
}

public void insert(String word, int number) {
Node current = root;
for (int i = 0; i < word.length(); ++i) {
int index = word.charAt(i) - 'A';
if (null == current.getChildrenItem(index)) {
current.setChildrenItem(index, new Node(new Node[26], null, -1));
}
current = current.getChildrenItem(index);
}
current.setNumber(number);
current.setLength(word.length());
}

public void build() {
Queue<Node> queue = new LinkedList<Node>();
queue.offer(root);
while (!queue.isEmpty()) {
Node current = queue.poll();
for (int i = 0; i < 26; ++i) {
if (null != current.getChildrenItem(i)) {
if (current == root) {
current.getChildrenItem(i).setFail(root);
} else {
Node fail = current.getFail();
while (null != fail) {
if (null != fail.getChildrenItem(i)) {
current.getChildrenItem(i).setFail(
fail.getChildrenItem(i));
break;
}
fail = fail.getFail();
}
if (null == fail) {
current.getChildrenItem(i).setFail(root);
}
}
queue.offer(current.getChildrenItem(i));
}
}
}
}

public ArrayList<Node> search(String str) {
Node current = root;
ArrayList<Node> list = new ArrayList<Node>();
for (int i = 0; i < str.length(); ++i) {
int index = str.charAt(i) - 'A';
while (null == current.getChildrenItem(index) && current != root) {
current = current.getFail();
}
current = current.getChildrenItem(index);
if (null == current) {
current = root;
}
Node end = current;
while (null != end && end != root) {
if (-1 != current.getNumber()) {
current.setStart(i - current.getLength() + 1);
list.add(current);
break;
}
end = end.getFail();
}
}
return list;
}

}

class Node {

private Node[] children;
private Node fail;
private int number; // 点的编号
private int length; // 字符串长度
private int start; // 在trie中找到的字符串在矩阵的字符串中的开始位置

public Node(Node[] children, Node fail, int number) {
this.children = children;
this.fail = fail;
this.number = number;
}

public Node getChildrenItem(int i) {
return children[i];
}

public void setChildrenItem(int i, Node node) {
children[i] = node;
}

public Node getFail() {
return fail;
}

public void setFail(Node fail) {
this.fail = fail;
}

public int getNumber() {
return number;
}

public void setNumber(int number) {
this.number = number;
}

public int getLength() {
return length;
}

public void setLength(int length) {
this.length = length;
}

public int getStart() {
return start;
}

public void setStart(int start) {
this.start = start;
}

}

class NodeResult implements Comparable<NodeResult> {

private int x;
private int y;
private char direction;
private int number;

public NodeResult(int x, int y, char k, int number) {
this.x = x;
this.y = y;
this.direction = k;
this.number = number;
}

public int getX() {
return x;
}

public int getY() {
return y;

4000
}

public char getDirection() {
return direction;
}

@Override
public int compareTo(NodeResult nodeResult) {
return this.number - nodeResult.number;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM POJ 1204 JAVA