之前上高中的时候打游戏时想到的一道题目
扑克飞镖:每使用一次法力值消耗增加1点 初始法力值为零费 每次使用后回手
吹气:获得五点法力值 手牌中法力值最高的牌消耗归零
假设魔术师现在手中仅有上述两张手牌 且两张牌的配合机制如下: 当打出吹气后 扑克飞镖的法力值重新计算(即首项为零 公差为一的等差数列)
请问:(1).当魔术师初始法力值为25 求本回合中她最多可以打出几次“扑克飞镖”?
(2).当魔术师初始法力值为常数m时(m>0)求本回合中她最多可以打出几次“扑克飞镖”? (注:(1)与(2)中“吹气”必须打出)
当然,如果这道题要编程来解决的话,不妨直接做第二题好了。
我的思路:首先先确定下来如果不重置费用(也即不打出吹气)的情况下最多打出几次飞镖。这个可以用求根公式加高斯函数来算。然后对于每一种可能打出吹气的位置(也即大于等于0次,小于等于不打吹气的最大次数),计算该情况下的次数,并与已经出现的最大次数相比对。
代码如下
/*
扑克飞镖:每使用一次法力值消耗增加1点 初始法力值为零费
吹气:获得五点法力值 手牌中法力值最高的牌消耗归零
假设魔术师现在手中仅有上述两张手牌 且两张牌的配合机制如下:
当打出吹气后 扑克飞镖的法力值重新计算(即首项为零 公差为一的等差数列)
当魔术师初始法力值为正整数m时,求本回合中她最多可以打出几次“扑克飞镖”?
输入:一个合适的正整数 输出:最多打出扑克飞镖的次数
*/
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int N=scan.nextInt(),max=(int)((1+Math.sqrt(1+8*N))/2),cost=0,maxCount=0;
//max是不打吹气的情况下最多打几次飞镖
for(int i=0;i<=max;i++){//遍历每一种打出吹气的情况
int count=0;//某种情况下的次数
int temp=N;
while(N>=cost){
if(count==i){
cost=0;
N=N+5;
count++;//不写个count++这个if一直执行
continue;
}
N-=cost;
count++;
cost++;
}
if(count-1>maxCount){
maxCount=count-1;
}
N=temp;
cost=0;
}
System.out.print(maxCount);
}
}
我觉得在自己的代码中涉及到一些比较丑陋的地方,首先是第23行的count++,如果不写这一句到了count加到i的时候就会一直执行这个if,导致死循环,所以只能先在这里给它加上,理解成现在打了几张牌,而吹气时有且仅有1张的,那么最后减1,就是打出飞镖的次数。
其次是N和cost在循环中不断改变,每次内循环结束后我只能加个存储器重新赋值。
最后是算法问题,两个循环嵌套会不会复杂度太高?有没有这个思路下更好的数学优化算法或者是其他思路和算法?感谢大家的交流和帮助!