EOJ 205. 数列项

单点时限: 2.0 sec

内存限制: 256 MB

非负数列项的第1项为0,第2项为1,后面的每项为其前面的 k(2≤k≤10) 项之和(若不存在前面的某个项,计算时以0表示)。
例如: k=3, 则数列项依次为:0,1,1(因前面的项不足3项,计算时以(0)表示,1+0+(0)=1),2,4,……

输入格式
一行由一个空格分隔的正整数 k 和 n。

80%的数据点: 2≤k≤3,1≤n≤10

10%的数据点: 2≤k≤5,1≤n≤50

10%的数据点: 2≤k≤10,1≤n≤100

输出格式
在一行中输出数列的第n项。

样例

input
2 1
output
0
input
4 6
output
8
input
3 4
output
2

思路
一道大数运算题
因为每个数都是前k个数的和并且后面的数一定大于前面的数,所以只需要申请一个k行的二维数组来存放数据。
如果n小于2则直接输出。
通过对下标取模定位到数字所在行,将该行更新为k个数字之和。也就是说对于第i个数的第j位而言,它的数码是所有行的第j位的和再模10。直到把这一行处理完,即新的数字替换了旧的数字。简单说就是模拟一个k个数的竖式加法计算。处理了n-2次(0行和1行初始化为0和1)后退出循环,将目标行从后往前输出即可(去掉前置0)。

ac代码

#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) 
{
	int k,n;
	cin >> k >> n;
	int res[k][100];
	for(int i=0;i<k;i++)
	{
		for(int j=0;j<100;j++)
			res[i][j]=0;
	}
	res[1][0]=1;
	if(n==1) cout << 0;
	else if(n==2) cout << 1;
	else
	{
		for(int i=2;i<n;i++)
		{
			int sum=0,carry=0;
			for(int j=0;j<100;j++)
			{
				sum=0;
				for(int m=0;m<k;m++)
					sum+=res[m][j];
				sum+=carry;
				res[i%k][j]=sum%10;
				carry=sum/10;
			}
		}
		int flag;
		for(flag=99;res[(n-1)%k][flag]==0;flag--) ;
		for(;flag>=0;flag--)
			cout << res[(n-1)%k][flag];
	}
	return 0;
}
原创文章 9 获赞 10 访问量 662

猜你喜欢

转载自blog.csdn.net/qq_45401156/article/details/105714744