三枪客
* 求存活概率问题*
* 三个小伙子同时爱上了一 个姑娘,为了决定他们谁能娶这个姑娘,他们决定用手枪进行一次决斗。
* 小李的命中率是30%,
* 小黄比他好些,命中率是50%,
* 最出色的枪手是小林,他从不失 误,命中率是100%。
* 由于这个显而易见的事实,为公平起见,他们决定按这样的顺序:小李先开枪,小黄第二,小林最后。
* 然后这样循环,直到他们只剩下一个 人。
* 那么这三个人中谁活下来的机会最大呢?他们都应该采取什么样的策略?
*
* 很明显:
* 小李应该先向小林射击,因为如果他向小黄射击,如果碰巧击中那他之后必死无疑,既然这样先向小黄
* 射击就没有意义了。
* 而小黄在小林还活着的情况,肯定也先向小林开枪。
* 而小林在小黄还活着的情况下自然先向命中率更高的小黄开枪。
*/
public class Shoot { <span style="white-space:pre"> </span>private boolean isFirstAlive; <span style="white-space:pre"> </span>private boolean isSecondAlive; <span style="white-space:pre"> </span>private boolean isThirdAlive; <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>private long firstAliveNum = 0; <span style="white-space:pre"> </span>private long secondAliveNum = 0; <span style="white-space:pre"> </span>private long thirdAliveNum = 0; <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>private static Map<Boolean, Integer> counterDict = new HashMap<Boolean, Integer>(); <span style="white-space:pre"> </span>static{ <span style="white-space:pre"> </span>counterDict.put(true, 1); <span style="white-space:pre"> </span>counterDict.put(false, 0); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>private void init(){ <span style="white-space:pre"> </span>isFirstAlive = true; <span style="white-space:pre"> </span>isSecondAlive = true; <span style="white-space:pre"> </span>isThirdAlive = true; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>private void clear(){ <span style="white-space:pre"> </span>firstAliveNum = 0; <span style="white-space:pre"> </span>secondAliveNum = 0; <span style="white-space:pre"> </span>thirdAliveNum = 0; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 如果小黄第一次不放空枪 <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>public void startGame(){ <span style="white-space:pre"> </span>init(); <span style="white-space:pre"> </span>int shootNum = 0; <span style="white-space:pre"> </span>while(!isGameOver()){ <span style="white-space:pre"> </span>if(isFirstAlive){ <span style="white-space:pre"> </span>shootNum = (int) (Math.random() * 10); <span style="white-space:pre"> </span>if(shootNum <= 2){ <span style="white-space:pre"> </span>if(isThirdAlive){ <span style="white-space:pre"> </span>isThirdAlive = false; <span style="white-space:pre"> </span>}else{ <span style="white-space:pre"> </span>isSecondAlive = false; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>if(isSecondAlive){ <span style="white-space:pre"> </span>shootNum = (int) (Math.random() * 2); <span style="white-space:pre"> </span>if(shootNum == 1){ <span style="white-space:pre"> </span>if(isThirdAlive){ <span style="white-space:pre"> </span>isThirdAlive = false; <span style="white-space:pre"> </span>}else{ <span style="white-space:pre"> </span>isFirstAlive = false; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>if(isThirdAlive){ <span style="white-space:pre"> </span>if(isSecondAlive){ <span style="white-space:pre"> </span>isSecondAlive = false; <span style="white-space:pre"> </span>}else{ <span style="white-space:pre"> </span>isFirstAlive = false; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>if(isFirstAlive){ <span style="white-space:pre"> </span>firstAliveNum++; <span style="white-space:pre"> </span>}else if(isSecondAlive){ <span style="white-space:pre"> </span>secondAliveNum++ ; <span style="white-space:pre"> </span>}else{ <span style="white-space:pre"> </span>thirdAliveNum++; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 如果小黄第一次放空枪 <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>public void startGame2(){ <span style="white-space:pre"> </span>init(); <span style="white-space:pre"> </span>int shootNum = 0; <span style="white-space:pre"> </span>while(!isGameOver()){ <span style="white-space:pre"> </span>// 小黄还活着,由他射击 if(isSecondAlive) { // 如果小林还活着就先向小黄开枪,毫无疑问;否则向小李开枪 shootNum = (int)(Math.random() * 2); if(shootNum == 1) { // 命中率为二分之一 if(isThirdAlive) { isThirdAlive = false; } else { isFirstAlive = false; } } } // 神枪手小林还活着 if(isThirdAlive) { // 如果小黄还活着,先向他射击 if(isSecondAlive) { isSecondAlive = false; } else { isFirstAlive = false; } } // 小李还存活,由他射击 if(isFirstAlive) { // 如果小林还存活就向小林开枪,如果小林挂了,那么说明小黄还活着,则向小黄开枪 shootNum = (int)(Math.random() * 10); if(shootNum <= 2) { // 命中率为十分之三 if(isThirdAlive) { isThirdAlive = false; } else { isSecondAlive = false; } } } <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>if(isFirstAlive){ <span style="white-space:pre"> </span>firstAliveNum++; <span style="white-space:pre"> </span>}else if(isSecondAlive){ <span style="white-space:pre"> </span>secondAliveNum++ ; <span style="white-space:pre"> </span>}else{ <span style="white-space:pre"> </span>thirdAliveNum++; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>public void startGame(long num, boolean isFirstShootNull){ <span style="white-space:pre"> </span>clear(); <span style="white-space:pre"> </span>for(int i= 0; i< num; i++){ <span style="white-space:pre"> </span>if(isFirstShootNull){ <span style="white-space:pre"> </span>startGame2(); <span style="white-space:pre"> </span>}else{ <span style="white-space:pre"> </span>startGame(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>System.out.println("执行次数:"+num); <span style="white-space:pre"> </span>System.out.println("小李获胜概率:"+ BigDecimal.valueOf((double)firstAliveNum/num*100).divide(BigDecimal.valueOf(1), 4, RoundingMode.HALF_UP)+"%"); <span style="white-space:pre"> </span>System.out.println("小黄获胜概率:"+ BigDecimal.valueOf((double)secondAliveNum/num*100).divide(BigDecimal.valueOf(1), 4, RoundingMode.HALF_UP)+"%"); <span style="white-space:pre"> </span>System.out.println("小林获胜概率:"+ BigDecimal.valueOf((double)thirdAliveNum/num*100).divide(BigDecimal.valueOf(1), 4, RoundingMode.HALF_UP)+"%"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>private boolean isGameOver() { <span style="white-space:pre"> </span>return counterDict.get(isFirstAlive) + counterDict.get(isSecondAlive) + counterDict.get(isThirdAlive) == 1; <span style="white-space:pre"> </span>} }
public class ShootMain { /** * @param args */ public static void main(String[] args) { Shoot shoot = new Shoot(); System.out.println("小李第一不放空枪----------------------"); shoot.startGame(1000000, false); System.out.println("------------------------------------"); System.out.println("小李第一枪放空枪----------------------"); shoot.startGame(1000000, true); System.out.println("------------------------------------"); } }