题目描述:
Total Submission(s): 389 Accepted Submission(s): 184
KK's Steel
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 389 Accepted Submission(s): 184
Problem Description
Our lovely KK has a difficult mathematical problem:he has a
N(1≤N≤1018)
meters steel,he will cut it into steels as many as possible,and he doesn't want any two of them be the same length or any three of them can form a triangle.
Input
The first line of the input file contains an integer
T(1≤T≤10)
, which indicates the number of test cases.
Each test case contains one line including a integer N(1≤N≤1018) ,indicating the length of the steel.
Each test case contains one line including a integer N(1≤N≤1018) ,indicating the length of the steel.
Output
For each test case, output one line, an integer represent the maxiumum number of steels he can cut it into.
Sample Input
1 6
Sample Output
3Hint1+2+3=6 but 1+2=3 They are all different and cannot make a triangle.
题意:
对于一条长为N(1≤N≤1018)米的钢管,最多可以锯成几根小钢管,使得锯成的钢管互不相等且均不能围成三角形。
解析:
一开始拿到题目的时候,只有短短的一句话,我们可能无从下手,当自己无从下手的时候,那么我们便可以枚举出前几种比较简单的情况,从而找出一般规律。由题意我们可以知道,锯成的钢管的长度至少为1,而任意的三根钢管又都不能围成三角形,并且锯成的钢管数目要最多,那么第二段钢管长度只能是2,同理,第三段钢管的长度只能是3,第四段是5,第五段是8.因此我们可以得出以下的数列:
1,2,3,5,8......
看到以上的数列,便立马反应过来了,这便是斐波那契数列。我们可以预处理出斐波那契数列的前n项和,然后再遍历即可。所以得出以下完整代码:
#include<cstdio>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const int maxn = 100;
ull ans[maxn+5];
int main()
{
int T;
ull a1 = 1,a2 = 2;
ull sum;
ans[1] = 1;
ans[2] = 3;
for(int i = 3; i < 100; i++) //预处理出斐波那契数列前n项和
{
sum = a1 + a2;
ans[i] = ans[i-1] + sum;
a1 = a2;
a2 = sum;
}
scanf("%d",&T);
while(T--)
{
ull N;
scanf("%I64u",&N);
for(int i = 1; i < 100; i++)
{
if(N < ans[i])
{
printf("%d\n",i-1);
break;
}
}
}
return 0;
}
总结:当拿到一道没有头绪的题目时,可以从简单到复杂寻找规律,枚举当n=1,2,3,4...的情况,然后再总结出一般规律