本身只是BFS搜索,需要注意的有几点:
1. 题目中的modulus操作与计算机的%不同。modulus(a,b) = (a%b+b)%b。 即保证结果一定为正。而计算机中是先abs(a)%b,再把a符号付给它。
2. 在搜索过程中值会越来越大,不便于存入hash数组,由于计算的值总是用于比较modulus(tmp, K)==modulus(N+1,K),因此我们可以不必保存tmp,而直接对tmp取modulus。
3. 由于存在modulus(tmp, M)的OP,因此要保证tmp一直还与M线性同余。取tmp = modulus(tmp,KM),这样既可以保证tmp比较小,又保证与K,M都线性同余,使得之后的modulus(tmp,K)和modulus(tmp,M) 效果都与不对tmp进行任何处理效果相同。
4.注意Node中存的和hash的都是经过处理的tmp值。每次检查是否得到正确结果,需要检查 modulus(经过处理的tmp,K)==modulus(N+1,K)
import java.util.*; public class Main { String ops = "+-*%"; class Node { int n; String path; } int N, K, M, result, KM; Scanner input = new Scanner(System.in); LinkedList<Node> list = new LinkedList<Node>(); boolean[] hash = new boolean[1000001]; public static void main(String[] args) { new Main().work(); } public int modulus(int a, int b) { return (a % b + b) % b; } public void work() { while (input.hasNext()) { N = input.nextInt(); K = input.nextInt(); M = input.nextInt(); if (N == 0 && K == 0 && M == 0) { break; } KM = K * M; list.clear(); Arrays.fill(hash, false); Node head = new Node(); head.path = ""; head.n = N; hash[modulus(N, KM)] = true; result = modulus(N + 1, K); list.add(head); bfs(); } input.close(); } public void bfs() { while (!list.isEmpty()) { Node node = list.poll(); if (modulus(node.n, K) == result) { System.out.println(node.path.length()); System.out.println(node.path); return; } for (int i = 0; i < ops.length(); i++) { doOp(ops.charAt(i), node); } } System.out.println(0); } public void doOp(char op, Node node) { int tmp = 0; switch (op) { case '+': tmp = modulus(node.n + M, KM); break; case '-': tmp = modulus(node.n - M, KM); break; case '*': tmp = modulus(node.n * M, KM); break; case '%': tmp = modulus(modulus(node.n, M), KM); break; } if (!hash[tmp]) { hash[tmp] = true; Node newNode = new Node(); newNode.path = node.path + op; newNode.n = tmp; list.addLast(newNode); } } }