import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class Solution { private static final int DEPTH_LIMIT = 6; private static final int MOVE_BIT_SIZE = 3; private int discsCount; private int pegsCount; private long startPegs; private long finalPegs; private int mask; public void init(InputStream is) { Scanner in = new Scanner(is); String str = in.nextLine(); String[] tokens = str.split(" "); discsCount = Integer.parseInt(tokens[0]); pegsCount = Integer.parseInt(tokens[1]); startPegs = readConfig(in.nextLine()); finalPegs = readConfig(in.nextLine()); mask = (1 << discsCount) - 1; } private long readConfig(String str){ String[] tokens = str.split(" "); int k = 0; int[] startCfg = new int[pegsCount]; for (int i = 0; i < discsCount; i++) { k = Integer.parseInt(tokens[i]) - 1; startCfg[k] = startCfg[k] | (1 << i); } k = 0; long config = 0l; for (long peg : startCfg) { config |= peg << (discsCount * k++); } return config; } public void find() { Queue<Long> q = new LinkedList<Long>();//pegs configurations Queue<Integer> p = new LinkedList<Integer>();//moves path q.add(startPegs);//start from initial configuration int parentPath = 0;//parent path p.add(parentPath); int path = 0;//child path long curCfg = 0;//current configuration int movesCnt = 0;//count of moves int fromPeg = 0; int toPeg = 0; long fromPegCfg = 0; long toPegCfg = 0; int fromLeastBit = 0; int toLeastBit = 0; int[] levelSize = new int[DEPTH_LIMIT + 1]; levelSize[0] = 1; while (!q.isEmpty() && movesCnt < DEPTH_LIMIT) { curCfg = q.poll(); parentPath = p.poll(); for (int i = 0; i < pegsCount; i++) { fromPegCfg = (curCfg >>> (discsCount * i)) & mask; fromLeastBit = discsCount; if (fromPegCfg > 0){ fromLeastBit = 0; while (((fromPegCfg >>> fromLeastBit) & 1) == 0) { fromLeastBit++; } } for (int j = i + 1; j < pegsCount; j++) { fromPeg = i; toPeg = j; toPegCfg = (curCfg >>> (discsCount * j)) & mask; if (fromPegCfg == toPegCfg){ //exclude empty pegs continue; } toLeastBit = discsCount; if (toPegCfg > 0){ toLeastBit = 0; while (((toPegCfg >>> toLeastBit) & 1) == 0) { toLeastBit++; } } if (fromLeastBit > toLeastBit){ fromPeg = j; toPeg = i; } else { toLeastBit = fromLeastBit; } toPegCfg = curCfg; toPegCfg |= (1 << ((discsCount * toPeg) + toLeastBit)); toPegCfg ^= (1 << ((discsCount * fromPeg) + toLeastBit)); assert checkDiscs(toPegCfg) : i + ":" + j + " " + Long.toBinaryString(toPegCfg) + "->" + Long.toBinaryString(toPegCfg); if (toPegCfg == finalPegs) { long movesPath = parentPath; movesPath |= (fromPeg << (movesCnt * 2 * MOVE_BIT_SIZE)); movesPath |= (toPeg << ((movesCnt * 2 + 1) * MOVE_BIT_SIZE)); print(movesCnt + 1, movesPath); return; } else if (movesCnt < DEPTH_LIMIT) { q.add(toPegCfg); path = parentPath | (fromPeg << (movesCnt * 2 * MOVE_BIT_SIZE)); path |= (toPeg << ((movesCnt * 2 + 1) * MOVE_BIT_SIZE)); p.add(path); } levelSize[movesCnt + 1]++; } } if (--levelSize[movesCnt] == 0) { movesCnt++; } } } private boolean checkDiscs(long config){ long checked = 0; for(int i=0; i < pegsCount; i++){ checked += (config >>> (i * discsCount)) & mask; } return checked == mask; } public void print(int movesCount, long movesPath){ System.out.println(movesCount); int moveMask = (1 << MOVE_BIT_SIZE) - 1; int k = 0; int pegFrom = 0; int pegTo = 0; while(k < movesCount){ pegFrom = (int)(movesPath >>> (k * 2 * MOVE_BIT_SIZE)) & moveMask; pegTo = (int)(movesPath >>> ((k * 2 + 1) * MOVE_BIT_SIZE)) & moveMask; System.out.println((pegFrom + 1) + " " + (pegTo + 1)); k++; } } /** * @param args */ public static void main(String[] args) { Solution solution = new Solution(); //String input = "6 4\n" + "4 2 4 3 1 1\n" + "4 4 4 3 2 1\n"; //ByteArrayInputStream bais = new ByteArrayInputStream(input.getBytes()); //solution.init(bais); solution.init(System.in); solution.find(); } }
пятница, 21 октября 2011 г.
Колышки и колечки - решение
Как и обещал ранее предлагаю свое решение к задаче из предыдущего поста. Правда не было времени прокомментировать - сделаю позже.
Ярлыки:
головоломка,
puzzle
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий