蛋蛋的问题(三)
时间限制:1000 ms | 内存限制:65535 KB
难度:3
- 描述
-
这学期到了十一周了,蛋蛋突然要去金工实习了,想到要拿着锉刀,钳子,锯子什么的做锤子了,头就有点大了,因为它挺好玩的,但是,也是很累的,看着学弟坐在机房悠闲地敲着代码,蛋蛋学长决定要让他们好好忙忙,这道题就是为了你们而出的,学弟们,加油!!
问题很简单,只是需要动手就够了,要求是,给你n米长的钢筋,钢筋大家都知道吧,就是一根钢条,目的很简单,让你自己动手把这一根很长的钢筋切成M段,保证他们中的任意三段都不能构成三角形,听起来会感觉乱乱的,其实我要的答案很简单,就是你能把这根钢筋截成多少条,条数要最多,还有就是长度不能少于1米。
简单吧,大家抓紧时间AC吧。
- 输入
- 有多组数据,每组数据只有一行,一行里面只有一个数N(4<=N<=1000000); 输出
- 输出占一行,对应每个N输出最多的条数M 样例输入
-
7 144
样例输出 -
4 10
题目要求“让你自己动手把这一根很长的钢筋切成M段,保证他们中的任意三段都不能构成三角形 ”以下是提交成功代码,跳出for循环的条件是t-a[i]<0,若此时t!=0,也会跳出,此时钢条会剩下一截长(度小于a[i]),这段必定会与其它段形成三角形,所以这样写与题意不符,而提交结果竟然正确。
#include<stdio.h> #define N 47 int a[N]={0,1,1,2}; int main() { int i,j,t,n; for(i=2;i<N;i++) a[i]=a[i-1]+a[i-2]; // for(i=1;i<N;i++) while(scanf("%d",&t)!=EOF) { // printf("%d %d\n",i,a[i]); int s=0; for(i=1;i<N;i++) { if(t-a[i]<0) break; t-=a[i]; ++s; } printf("%d\n",s); } return 0; }
如下应该是正确的完成方式:
#include<stdio.h>
#include<string.h>
#define N 47
int a[N]={0,1};
int b[50];
int main()
{
int i,j,t,n;
memset(b,0,sizeof(int)*50);
for(i=2;i<N;i++)
a[i]=a[i-1]+a[i-2];
// for(i=1;i<N;i++)
// printf("%d %d\n",i,a[i]);
while(scanf("%d",&t)!=EOF)
{
int s=0;
for(i=1;i<N;i++)
{
if(t-a[i]<0)//当t值小于a[i],说明前面的截法有问题,不能满足截下来的任意三段不能构成三角形的条件,
//也说明a[i]这一段是必须的一截,前面的截法需要调整,所以执行for循环。
for(t=a[i]-t,s++,j=i-1,b[i]=a[i];j>=1;j--)//t=a[i]-t是求凑够a[i]长度还需要的长度;s++算上a[i]这截;
{ //可以验证a[i]之前诸项能够表示小于它的任何数,程序另附
//printf("t====%d\n",t);
if(t==0)
break;
if(t-a[j]>=0)
{
t-=a[j];
s--;
b[j]=0;
//printf("sin=%d\n",s);
}
}
if(t==0) //此处break与下面的break,含义不同,此处针对内for循环后结束外for循环
break;
t-=a[i];
b[i]=a[i];
//printf("i=%d t=%d\n",i,t);
++s;
if(t==0)
break;
// printf("sout=%d\n",s);
}
printf("%d\n",s);
printf("切割方法是:\n");
for(i=0;i<50;i++)
if(b[i]!=0)
printf("%d ",b[i]);
printf("\n");
}
return 0;
}
//证明这组数中小于最大项的数能表示为最大项前面诸项的和
#include<stdio.h>
#define N 47
#define NUM 100000
int a[N]={0,1};
int b[N]={0,1};
int main()
{
int i,s,t,n;
for(i=2;i<N;i++)
{
a[i]=a[i-1]+a[i-2];
b[i]=a[i];
}
for(s=1;s<NUM;s++)
//while(scanf("%d",&j))
{
int Q=0;
int j=0,di=0;
j=s;
for(i=1;i<N;i++)
if(j>=a[i]&&j<a[i+1])
di=i;
printf("num= %d\n",s);
for(i=di;i>0;i--)
{
if(j==0)
{
Q=1;
break;
}
if(j>=a[i])
j-=a[i];
}
if(!Q)
printf("%d is wrong!\n",j);
}
return 0;
}