【搜索】HDU1104

本身只是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);
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值