扑克牌重排问题

问题描述:
手上有13张牌,从上往下依次做如下操作:
第1张牌放桌上,第2张挪到手牌的最下面,第3张叠在桌上,第4张挪到手牌的最下面...
一直重复上述过程,直至手上所有的牌都叠在桌上。

叠在桌上的牌,从下往上的次序依次是1、2、3...13
要求-还原操作之前,手牌的次序。

算法分析:
手上的牌,从上到下的次序,
依次编号A1、A2、A3...A13,

挪到桌上之后的次序:
A8、A12、A4、A10、A6、A2、A13、A11、A9、A7、A5、A3、A1

经过分析-
挪放前的手牌,
不能被2^1整除的编号,在桌上的最下方,编号从下到上依次递增...
然后是不能被2^2整除的编号,在桌上的次最下方,编号从下到上依次递增...
然后是不能被2^3整除的编号,在桌上的次次最下方,编号从下到上依次递增...
...
然后是不能被2^countMaxTimes整除的编号,在最上方,编号从下到上依次递增。

JAVA代码编码实现:

package algorithm.poker;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.testng.annotations.Test;

/**   
* @date 2018年5月8日  
*/
public class ReSortPorker {
	private int []targetArray;
	public ReSortPorker(int[]targetArray) {
		this.targetArray = targetArray;
	}
	
	public static Map<Integer, List<Integer>> getResortResult(int[]targetArray){
		ReSortPorker reSortPorker = new ReSortPorker(targetArray);
		return reSortPorker.getResortResult();
	}
	
	private Map<Integer, List<Integer>> getResortResult(){
		int maxCount=countMaxTimes(1, 2, this.targetArray.length);
		Map<Integer, List<Integer>> map = new TreeMap<Integer, List<Integer>>();
		/**
		 * 每个下标index从2^1 ~ 2^countMaxTimes都遍历一遍,
		 * 碰到不能整除的2^x 则map.get(2^x).add(index),同时停止遍历
		 */
		for(int index=0;index<targetArray.length;index++) {
			for(int i=1;i<=maxCount;i++) {
				if (dowithMap(index, get2n(i), map)) {
					break;
				}
			}
		}
		return map;
	}
	
	/**
	 * @param index 遍历0~targetArray.length-1
	 * @param base 
	 * @param map
	 * 
	 * 如果(index+1)%(2^base)!=0
	 * @return false && map.get(base).add(index);
	 */
	private boolean  dowithMap(int index,int base,Map<Integer, List<Integer>>map) {
		if ((index+1)%base==0) {
			return false;
		}
		if (map.get(base)==null) {
			List<Integer> _baseList = new ArrayList<Integer>();
			_baseList.add(index);
			map.put(base, _baseList);
		}else {
			map.get(base).add(index);
		}
		return true;
	}
	
	/**
	 * @param n
	 * @return 2^n
	 */
	private int get2n(int n) {
		if (n==0) {
			return 1;
		}else {
			return 2*get2n(n-1);
		}
	}
	/**
	 * @param times
	 * @param intValue
	 * @param target
	 * 
	 * 如果数组元素的个数2^(n-1)<targetArray.length<2^n
	 * @return n
	 */
	private int countMaxTimes(int times,int intValue,int target) {
		if (times<=0) {
			return -1;
		}
		if (intValue>target) {
			return times;
		}
		if (2*intValue>target) {
			return times+1;
		}else {
			return countMaxTimes(times+1, 2*intValue, target);
		}
	}
	
	@Test
	public static void f() {
		Map<Integer, List<Integer>>map = ReSortPorker.getResortResult(new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13});
		for(int key:map.keySet()) {
			for(int i=0;i<map.get(key).size();i++) {
				System.err.println(map.get(key).get(i)+1);
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/wwHRestarting/article/details/80251744