例:尼科彻斯定理的内容是:任何一个整数的立方都可以写成一串连续奇数的和。编程验证该定理。
核心算法与分析:
一串连续奇数的和就是公差为2(步长)的递增或递减数列求和,很明显要使用循环语句,作为递减数列从最大值开始累加更快
①不知道循环变量的初值(递减数列的首项),但是可以构造外层循环,在一定范围内对递减数列的首项(大于等于1,可作为外层循环条件)进行遍历,再在每一个首项(最大值)的情况下都进行内层循环
确定外层循环的初值:
由于除sum==1时外,至少是两个奇数相加
当sum/2是奇数时,如果以sum/2+2为最大值,两项累加(sum/2+2)+sum/2>sum,故此时最大值的上限小于(sum/2+2),即从sum/2开始遍历首项
当sum/2是偶数时,而我们要找的是一个奇数,(sum/2-1)or (sum/2+1) ?
如果以sum/2+1为最大值,两项累加(sum/2+1)+(sum/2-1)=sum
故从sum/2开始遍历②不知道循环变量的末值(即循环条件),但可以在循环体中使用if-break语句代替循环条件终止循环
当即时累加和等于立方值时,输出累加过程并跳出内层和外层循环
当即时累加和大于立方值时,说明外层遍历到的初值不对,跳出内层循环
当即时累加和小于立方值时,继续进行内层累加所以程序中使用了两个whilie语句,第一个while语句从可能的最大值开始直到1为止进行穷举,第二个while循环通过第一个while循环所确定的i值每次减2逐次累加求和,当累加和等于立方值时,输出累加过程并跳出循环,当累加和大于立方值时,也同样跳出第二个循环回到第一个循环中。
#include<stdio.h>
int main()
{
int n,sum,result,index,i,j,flag=1;
printf("请输入一个数:\n");
scanf("%d",&n);
sum=n*n*n;/*计算立方值*/
index=sum/2;/*sum/2为奇数时,确定这串连续奇数最大值的范围*/
if(index%2==0)/*sum/2为偶数时,确定这串连续奇数最大值的范围*/
index=index+1;
while(flag==1&&index>=1)/*此循环确定每次累加的最大值*/
{
result=0;
i=0;
while(1)/*在不同的最大值下进行累加*/
/*除非使用break语句,否则将永远不停地执行此累加循环*/
{
result+=index-i*2;/*每次循环往下加一个数,即时判断累加结果*/
if(result==sum)/*当此次累加和等于立方值时,输出累加过程并跳出循环*/
{
printf("%d*%d*%d=%d=",n,n,n,sum);
for(j=0;j<i;j++)
printf("%d+",index-j*2);
printf("%d\n",index-i*2);/*只有输完累加的最后一个数(j=i)后才能换行*/
flag=0;/*跳出外层循环,不再执行确定最大值的循环*/
break;/*跳出内层累加循环*/
}
if(result>sum)/*当累加和大于立方值时,跳出内层循环,减小最大值重新累加*/
break;
i++;
/*当累加和小于立方值时,继续累加*/
}
index-=2;/*改变累加时的最大值*/
}
return 0;
}
或
#include<stdio.h>
int main()
{
int n,sum,result,index,i,j,flag=1;
printf("请输入一个数:\n");
scanf("%d",&n);
sum=n*n*n;
index=sum/2;/*sum/2为奇数时,确定这串连续奇数最大值的范围*/
if(index%2==0)/*sum/2为偶数时,确定这串连续奇数最大值的范围*/
index=index+1;
if(index<1)
printf("error");
while(flag==1&&index>=1)/*此循环确定每次累加的最大值*/
{
for(i=0,result=0;;i++)
{
result+=index-i*2;
if(result==sum)/*当此次累加和等于立方值时,输出累加过程并跳出循环*/
{
printf("%d*%d*%d=%d=",n,n,n,sum);
for(j=0;j<i;j++)
printf("%d+",index-j*2);
printf("%d\n",index-i*2);
flag=0;
break;
}
if(result>sum)/*当累加和大于立方值时,跳出循环,减小最大值重新累加*/
break;
if(result<sum)/*当累加和小于立方值时,继续累加*/
continue;
}
index-=2;
}
return 0;
}