C++程序设计题解:2014年蓝桥杯C/C++程序设计A组(省赛)第十题——波动数列
题目描述
观察这个数列:
1 3 0 2 -1 1 -2 …
这个数列中后一项总是比前一项增加2或者减少3。
栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?
输入描述
输入的第一行包含四个整数 n s a b,含义如前面说述。
对于10%的数据,1<=n<=5,0<=s<=5,1<=a,b<=5; 对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30; 对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50; 对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50; 对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。
输出描述
输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以100000007的余数。
样例输入
4 10 2 3
样例输出
2
我的代码
//深度优先搜索
#include <iostream>
int count=0;
int s,a,b;
int arr[2];
using std::cin;
using std::cout;
using std::endl;
void dfs(int ,int ,int);
int main()
{
int n;
cin>>n>>s>>a>>b;//n为数的个数,s为和,增a,减b
//赋值arr[0]和arr[1]用于深度优先搜索的循环
arr[0]=a;
arr[1]=-b;
//(min+min+(n-1)*a)*n/2=s
//(max+max-(n-1)*b)*n/2=s
int min=s/n-(n-1)*a/2;
int max=s/n+(n-1)*b/2;
for(int i=min-1;i<=max+1;i++)//min-1,max+1扩大范围,
//抵消s/n时精度受损的影响
{
dfs(i,n-1,i);//深度优先搜索
}
cout<<count<<endl;
return 0;
}
void dfs(int i,int n,int res)//i表示上一项,n表示当前还需n项使
//数列完整,res为当前数列和
{
if(n==0)//当n为0,即n项数列已凑成
{
if(res==s)//如果数列和等于s
{
count++;//数列的个数增加1
return ;//返回
}
else
return;//返回
}
for(int j=0;j<=1;j++)
{
int t=i+arr[j];
dfs(t,n-1,res+t);//t为新项,res+t表示数列和
}
return;
}