#include <stdio.h>
long long t[55];
int fun()
{
t[1] = 1, t[2] = 2;
for(int i = 3; i <=50; i++)
t[i] = t[i - 1] + t[i - 2];
}
int main()
{
int N;
int a, b;
fun();
// for(int i = 1; i <= 50; i++)
// {
// printf("%lld|", t[i]);
// if(i%10 == 0)
// printf("\n");
// }
scanf("%d", &N);
while(N--) {
scanf("%d%d", &a, &b);
// printf("%d\n", t[b - a]);
printf("%lld\n", t[b - a]);
}
return 0;
}
解题思路
t[i]表示a–>b之间有i块
t
[
i
]
=
{
1
,
i
=
1
2
,
i
=
2
t
[
i
−
1
]
+
t
[
i
−
2
]
,
i
≥
3
t[i] = \begin{cases} 1, &i = 1 \\ 2, &i = 2 \\ t[i -1] + t[i - 2] , &i \ge 3 \end{cases}
t[i]=⎩⎪⎨⎪⎧1,2,t[i−1]+t[i−2],i=1i=2i≥3
遇到的问题
这道题思路很简单,但是提交了三次都直接WA,仔细读了代码,算法没有问题,那么就是最终答案输出错误,打了一下表:
1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 |
144 | 233 | 377 | 610 | 987 | 1597 | 2584 | 4181 | 6765 | 10946 |
17711 | 28657 | 46368 | 75025 | 121393 | 196418 | 317811 | 514229 | 832040 | 1346269 |
2178309 | 3524578 | 5702887 | 9227465 | 14930352 | 24157817 | 39088169 | 63245986 | 102334155 | 165580141 |
267914296 | 433494437 | 701408733 | 1134903170 | 1836311903 | -1323752223 | 512559680 | -811192543 | -298632863 | -1109825406 |
从表中可以清晰的看出随着i的增大,整形数据就溢出了,所以必须使用长整型
正确的数据应该是
1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 |
144 | 233 | 377 | 610 | 987 | 1597 | 2584 | 4181 | 6765 | 10946 |
17711 | 28657 | 46368 | 75025 | 121393 | 196418 | 317811 | 514229 | 832040 | 1346269 |
2178309 | 3524578 | 5702887 | 9227465 | 14930352 | 24157817 | 39088169 | 63245986 | 1023 | 34155 |
267914296 | 433494437 | 701408733 | 1134903170 | 1836311903 | 2971215073 | 4807526976 | 7778742049 | 12586269025 | 20365011074 |
总结
要正确分析数据的大小范围,选择合适的数据类型。