微软2017年预科生计划在线编程笔试题Legendary Items



题目1 : Legendary Items

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

Little Hi is playing a video game. Each time he accomplishes a quest in the game, Little Hi has a chance to get a legendary item.

At the beginning the probability is P%. Each time Little Hi accomplishes a quest without getting a legendary item, the probability will go up Q%. Since the probability is getting higher he will get a legendary item eventually.

After getting a legendary item the probability will be reset to ⌊P/(2I)⌋% (⌊x⌋ represents the largest integer no more than x) where I is the number of legendary items he already has. The probability will also go up Q% each time Little Hi accomplishes a quest until he gets another legendary item.

Now Little Hi wants to know the expected number of quests he has to accomplish to get N legendary items.  

Assume P = 50, Q = 75 and N = 2, as the below figure shows the expected number of quests is

2*50%*25% + 3*50%*75%*100% + 3*50%*100%*25% + 4*50%*100%*75%*100% = 3.25

输入

The first line contains three integers PQ and N.  

1 ≤ N ≤ 106, 0 ≤ P ≤ 100, 1 ≤ Q ≤ 100

输出

Output the expected number of quests rounded to 2 decimal places.

样例输入
50 75 2
样例输出
3.25



看了半天才看懂。


题意:每次完成一个没有legendary itemquest,概率会上升Q%(直到获得legendary item);完成legendary itemquest,概率重设为P/(2^I)%

反映到图中就是:每个节点的左节点为实心节点(完成legendary item的),右节点为空节点(未完成legendary item)。每个空节点(假设概率x)的左节点为x+q,实心节点的左节点概率为P/(2^I)% ,(图中每个节点的左右节点之和为100%)。求为了得到nlegendaryitem,需要多少quest

以上图为例,从上往下看,p50%n2时,最左边一直走,概率分别为:50%25%2legendary item),则停止

将整个树看作n层,从底层开始计算。

下面开始计算:自底向上,从最左的25%节点开始,这一点为0.25*0+1),此时不需往下走(因为已经拿到2legendary item)

右节点为1-0.25=0.75former),向下继续走概率为0.25+q=1(如果小于1,可以往下继续走),则概率为0.75*0+2)。至此两点之和0.25+0.75*2=1.75

25%的父节点为50%,则50%这一点为0.5*1.75+1),意思是这一点的子节点加上1level再乘以0.5就是这一点值

再看另外50%(右节点),former0.5,继续向下走为0.5*1.75+2),至此两点之和3.25




AC代码:

public class Main {
	public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int p = in.nextInt();
    	int q = in.nextInt();
    	int n = in.nextInt();
    	helper(p, q, n);
	}
	public static void helper(int p, int q, int n) {
		List<Integer> list = new ArrayList<Integer>();
    	list.add(p);
    	double r = 0;
    	for (int i = 1; i < n; i++) {
    		list.add(list.get(i - 1) / 2);
    	}
    	for (int m = n - 1; m >= 0; m--) {
    		int tmp = list.get(m);
    		double one = 0, former = 1;
    		int level = 1;
    		for (int j = tmp; ; j+= q) {
    			if (j > 100) {
    				j = 100;
    			}
    			one += former * ((double)j / 100)* (r + level) ;
    			former *= (1.0 - (double)j / 100.0);
  
    			level++;
    			if(j == 100) {
    			    break;
    			}
    		}
    		r = one;
    	}
    	System.out.print(r);
	}
}


再推荐一个这场笔试的讲解链接,分析的很好:

https://github.com/hiho-coder/msft-2017-online-test-solution/blob/master/README.md


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值