算法题--股神

题目描述:
有股神吗?
有,小赛就是!
经过严密的计算,小赛买了一支股票,他知道从他买股票的那天开始,股票会有以下变化:第一天不变,以后涨一天,跌一天,涨两天,跌一天,涨三天,跌一天…依此类推。
为方便计算,假设每次涨和跌皆为1,股票初始单价也为1,请计算买股票的第n天每股股票值多少钱?

输入输出
输入包括多组数据; 每行输入一个n,1<=n<=10^9请输出他每股股票多少钱,对于每组数据,输出一行
样例输入样例输出
11
22
31
42
53

分析:
  根据输入要求,输入的数量级为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;
}