三枪客


 * 求存活概率问题
 * 
 * 三个小伙子同时爱上了一 个姑娘,为了决定他们谁能娶这个姑娘,他们决定用手枪进行一次决斗。
 * 小李的命中率是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("------------------------------------");
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值