题目链接:http://exercise.acmcoder.com/online/online_judge_ques?ques_id=1664&konwledgeId=134
题目描述
有股神吗?
有,小赛就是!
经过严密的计算,小赛买了一支股票,他知道从他买股票的那天开始,股票会有以下变化:第一天不变,以后涨一天,跌一天,涨两天,跌一天,涨三天,跌一天...依此类推。
为方便计算,假设每次涨和跌皆为1,股票初始单价也为1,请计算买股票的第n天每股股票值多少钱?
解此题目的关键在于找出天数n和当天的每股股票的价值money的关系,通过如下表罗列对比我们可以发现:
(1)在每两次股票降跌的间隔期包括上一次降跌当天n和money的差值相同的,并且这些差值伴随每一次降跌增加2,即每次降跌时n和money的差值排列最终为一个等差数列,并且每阶段差值等于当前降跌次数i的两倍。也就是说n-money=2*i,最终伴随每次降跌i的排列是以0为初始值1为公差的等差数列
(2)找到n和money之间的关系后,我们发现增加了一个变量i(当前降跌次数),在题目中要求输入n输出money,也就是说n为已知量而money为未知量,所以我们还需要找到n和i之间的关系而不是money和i之间的关系;然后我们可以看到在每两次股票降跌的间隔期包括上一次降跌当天这几天n的个数和当前降跌次数i之间的差值固定在了2,那么也就是说只要n处于两次降跌之间,那么i的值不变,否则i的值随一次降跌加1。数学化i和n之间的关系:每个阶段n的个数为(i+2),而n的最小值为1,所以当前及之前所有阶段n的个数(i+2)累加(sum)等于当前n所处阶段的最后一次升涨的n值。由于i是伴随降跌的等差数列,所以(i+2)也是伴随降跌的等差数列,初始值为2,公差为1.
n | n-money=2*i | money | i | i+2个n |
1(0:不变) | 0 | 1 | 0 | 0+2个n Sum=2 |
2(+:升) | 0 | 2 | 0 | |
|
|
|
|
|
3(-:降) | 2 | 1 | 1 | 1+2个n Sum=2+3=5 |
4(+) | 2 | 2 | 1 | |
5(+) | 2 | 3 | 1 | |
|
|
|
|
|
6(-) | 4 | 2 | 2 | 2+2个n Sum=5+4=9 |
7(+) | 4 | 3 | 2 | |
8(+) | 4 | 4 | 2 | |
9(+) | 4 | 5 | 2 | |
|
|
|
|
|
10(-) | 6 | 4 | 3 | 3+2个n Sum=9+5=14 |
11(+) | 6 | 5 | 3 | |
12(+) | 6 | 6 | 3 | |
13(+) | 6 | 7 | 3 | |
14(+) | 6 | 8 | 3 | |
|
|
|
|
|
15(-) | 8 | 7 | 4 | 4+2个n Sum=14+6=20 |
16(+) | 8 | 8 | 4 | |
17(+) | 8 | 9 | 4 | |
18(+) | 8 | 10 | 4 | |
19(+) | 8 | 11 | 4 | |
20(+) | 8 | 12 | 4 |
代码实现:
import java.util.Scanner;
//赛题网股神
public class Warren {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
while( s.hasNextInt()) {
int money = computeMoney(s.nextInt());
System.out.print(money+" ");
}
s.close();
}
private static int computeMoney(int n) {
int money = 1;
int i = 0;
while(true){
// i初始值为0,如果n处于两次降跌之间,i值不变,即n大于等差数列(i+2)的前i项之和且小于等于前(i+1)项之和时,那么跳出循环计算money
if((i+3)*i<2*n&&2*n<=(i+4)*(i+1))break;
++i;
}
money = n -2*i;
return money;
}
}