算法题--股神
题目描述:
有股神吗?
有,小赛就是!
经过严密的计算,小赛买了一支股票,他知道从他买股票的那天开始,股票会有以下变化:第一天不变,以后涨一天,跌一天,涨两天,跌一天,涨三天,跌一天…依此类推。
为方便计算,假设每次涨和跌皆为1,股票初始单价也为1,请计算买股票的第n天每股股票值多少钱?
输入 | 输出 |
---|---|
输入包括多组数据; 每行输入一个n,1<=n<=10^9 | 请输出他每股股票多少钱,对于每组数据,输出一行 |
样例输入 | 样例输出 |
---|---|
1 | 1 |
2 | 2 |
3 | 1 |
4 | 2 |
5 | 3 |
分析:
根据输入要求,输入的数量级为10^9,如果按照基本思路,给一个循环加加减减运行效率很低,最好不要这样做,可以先找规律,我们可以推导规律,
股票总额为第一天为1, 第二天为1+1,第三天为1+1-1,第四天为1+1-1+1,第五天为1+1-1+1+1…,这么分析容易造成混乱,我们再来分析
题目描述,第一天不变,以后涨一天,跌一天,涨两天,跌一天,涨三天,跌一天…
也就是说,涨和跌有个周期,第一天单独考虑 第一个涨跌为1-1,第二个涨跌为2-1,第三个涨跌为3-1,第k个涨跌为k-1…涨和跌实际上都占有一个天数,第k个涨跌总共所需天数为(k+1)(k+2)/2,现在输入为n天,我们可以求出这是第几个涨跌周期,判断n天是属于第k-1个涨跌(k(k+1)/2)和第k个涨跌之前((k+1)(k+2)/2),求出这个k,我们就知道它属于哪个涨跌周期,最后股票总额=第k-1个涨跌周期股票总额(k(k-1)/2-k)+n天与第k-1个涨跌周期天数之差(n-(k(k+1)/2)+2),得出公式股票总额sum = n + 2 - 2*k
代码如下:
#include <iostream>
#include <vector>
int main(int args, char** argv)
{
int n = 0;
while (std::cin >> n)
{
int i = 1;
for (; i < n; ++i)
{
//第k-1个涨跌周期所需天数
int first = i * (i + 1)/2;
//第k个涨跌周期所需天数
int second = (i + 1) * (i + 2)/2;
if (n >= first && n < second)
break;
}
int sum = n + 2 - 2 * i;
std::cout << sum << std::endl;
}
return 0;
}