今天的内容主要是说昨天留给大家思考的问题,这个问题说难不难,就是有些麻烦,相信有同学已经得出答案了,不管如何,还是以前那句话,我们从头理一理吧。
从原题目入手,年龄的三次方是4位数,那么我们可以得出一个范围来,我们可以声明一个long类型变量来储存这个值
long sum1;
sum1的取值范围我们可以明确的知道大于1000并且小于10000。
(sum1>1000 && sum1 <>
接下来我们可以再从第二个条件知道,年龄的4次方是6位数,于是我们再声明一个long类型变量sum2来储存这个值,并且得到他的取值范围是在100000和1000000之间:
long sum2;
(sum2>100000 && sum2<>
说到这里,顺便说一下,算是补漏吧,千万不要写出下面类型的判断语句出来,这是C/C++不认同的:
(100000<><>
既然说到sum1和sum2,那么大家是不是想问,sum1和sum2的值从何而来?在C/C++里面的math.h库里有个power(n,m)函数,该函数返回n的m次方值,不过今天,我们不想直接使用这个库,我们自己写一个计算幂次方的函数来调用就好,反正是公众课,所以我想大家不会嫌代码多的是吧,下面我们就简单的先把幂次方的函数定义出来:
--------------------------------
long power(int n,int m)
{
long s=1;
while(m--)
{
s *= n;
}
return s;
}
-------------------------------
既然power已经定义好了,那么我们的sum1和sum2就顺理成章的计算出来了:
sum1 = power(i,3);
sum2 = power(i,4);
i是一个int变量,用来遍历年龄的,上面的代码如果不是因为教学的原因,可以不用写那个幂次方函数,直接使用i*i*i和i*i*i*i即可。
但是大家是不是发现一个问题,同学满足sum1和sum2的值不少,而且我们又看不见,难道说我们还要先把这个值打印出来再来研究这问题吗?其实本来有种思想就很简单的,就是自己预先演算一边,把同时满sum1和sum2的值计算出来,然后来用do while循环计算出年龄,这种方法要自己一个数字一个数字的去计算,不过可以根据我们大概的判断一下范围来围绕计算也不会是太难的,但是这不是我们今天要说的重点,毕竟我也很懒不想去想这个范围到底在哪里。既然这样,那我们把同时满足sum1和sum2的值的个数和最大值分别用一个函数计算出来,然后把他们传回main()中就可以了,下面我们分别实现返回个数和最大的两个函数:
----------------------------------------
//返回同时满足sum1和sum2的年龄数
int age()
{
int age[100];
int count = 0;
long sum1,sum2;
for(int i=0;i<>
{
sum1 = power(i,3);
sum2 = power(i,4);
if(sum1 > 1000 && sum1 <10000>10000>
sum2 > 100000 && sum2 <>
{
age[i] = i;
count++;
}
}
return count;
}
-------------------------------------
-------------------------------------
//返回满足sum1和sum2的最大值
int agemax()
{
int age[25]={0},max = 0;
long sum1,sum2;
for(int i=0;i<>
{
sum1 = power(i,3);
sum2 = power(i,4);
if(sum1 > 1000 && sum1 <10000 &&="">10000>
sum2 > 100000 && sum2 <>
{
age[i] = i;
}
if(max<>
{
max = age[i];
}
}
return max;
}
------------------------------------
两个函数差不多,如果我们直接使用打印输出的话只需要一个函数就好,但是我们现在是用他们的返回值来作为参数,所以我们把他们写成两个函数,分别返回不同的值。
我们现在知道最大值和个数,再加上这些数据都是连续的整数,所以我们通过最大值+1再减去个数便得到最小满足sum1和sum2的值。
这些都准备好了,现在我们可以回来设计我们的计算部分了,这里我们会使用do while来循环计算,wo while是我们今天的主角,所以现在来说说一下这个循环的用法。
----------------------------------
do
{
do something;
}while(条件);
-----------------------------------
从上面这个声明中,想必大家都清楚了,do while是先执行一遍程序然后再来判断满足否,如果不满足直接退出,如果满足继续循环,所以在三个循环函数中,可以根据具体的情况选择不同的循环来循环。
大家是不是还意识一点,在三个循环函数中,只有do while循环在while后面加分号,记住,这是一定要加的。
循环就是循环,没有什么花样,下面我们就用这个循环来计算昨天留下的问题,不过再给出最终代码之前,还是有先说一些必要的要点。
我们虽然得到一个范围,但是我们还有一个条件没有满足,那就是sum1和sum2里面没有重复的数字,这一点怎么来得出呢?首先我们要把sum1和sum2里面的所有数字取出来,怎么取?大家还记得前几讲说过的取余“%”运算符吗?现在我们就要用它和取整来对sum1和sum2取余,然后我们把每位都储存在一个数组里面,所以我们要在开头先声明一个数组,为了和早些时候的sum1和sum2区分开,我们这里声明为sum3和sum4操作如下:
--------------------------------
int a[10] = {0}//分辨用0来初始化
……
//对sum3
for(i=3;i>=0;i--)
{
a[i] = sum3%10;
sum /=10 ;// sum = sum/10;
}
//对sum4
for(i=9;i>3;i--)
{
a[i] = sum4%10;
sum4 /= 10;
}
------------------------------------
这样,我们便得到一个包含10个元素的数组,其中这10个元素要满足各不相同的条件,也就是他们分别是:0,1,2,3,4,5,6,7,8,9。那么怎么判断呢?我们可以再声明一个数组int s[10]={0},同样用0去初始化,然后用a[10]的元素去作为的下标,统计这些数字出现的次数,方法如下:
-------------------------------------
//统计数字出现的次数
for(i=0;i<>
{
s[a[i]]++;
}
--------------------------
接下来我们判断一下有没有重复的数字,方法如下:
------------------------------
//判断有没有重复数字然后顺便打印出结果
for(i=0;i<>
{
if(s[i] == 1)//如果有重复,就不会满足这个条件,然后会跳转到下面的break。
{
if(i == 9)//这个判断没多大意义,就是为了只打印一遍就好,否则会打印出10遍来。
printf(' 同学的年龄是:%d\n',c);
}
else
break;
}
------------------------------------
说到这里,想必大家应该都清楚了,下面是完整的程序清单,当然大家可以尝试一下简单的那个方法,就是自己预先算出能够满足sum1和sum2的值,然后再做循环,那样就不需要另外的三个程序。
----------------------------------------
//完整清单
#include
#include
long power(int n,int m);
int age();
int agemax();
int main()
{
int n,m,c;
long a[10]={0},s[10]={0},i,sum3,sum4;
n = age();
m = agemax();
c = m-n+1;
do
{
sum3 = power(c,3);
for(i=3;i>=0;i--)
{
a[i] = sum3%10;
sum3 = sum3/10;
}
sum4 = power(c,4);
for(i=9;i>3;i--)
{
a[i] = sum4%10;
sum4 = sum4/10;
}
for(i=0;i<>
{
s[a[i]]++;
}
for(i=0;i<>
{
if(s[i] == 1)
{
if(i == 9)
printf('这位同学的年龄是:%d\n',c);
}
else
break;
}
c++;
}while(c<>
system('PAUSE');
return 0;
}
//实现幂次方
long power(int n,int m)
{
long s=1;
while(m--)
{
s *= n;
}
return s;
}
//求满足sum1和sum2的个数
int age()
{
int age[25];
int count = 0;
long sum1,sum2;
for(int i=0;i<>
{
sum1 = power(i,3);
sum2 = power(i,4);
if(sum1 > 1000 && sum1 <10000 &&="">10000>
sum2 > 100000 && sum2 <>
{
age[i] = i;
count++;
}
}
return count;
}
//求出满足sum1和sum2的最大值
int agemax()
{
int age[25]={0},max = 0;
long sum1,sum2;
for(int i=0;i<>
{
sum1 = power(i,3);
sum2 = power(i,4);
if(sum1 > 1000 && sum1 <10000 &&="">10000>
sum2 > 100000 && sum2 <>
{
age[i] = i;
}
if(max<>
{
max = age[i];
}
}
return max;
}
-----------------------------------
现在我们来看下输出:
哦,原来臭小子是18岁啊,如果有持怀疑精神的可以自己推算一下吧,把这个程序理解后我相信大家不但学会了do while还学会了很多东西,好吧,今天就到这里,大家有兴趣证明一下尼科彻斯吗?
====================
尼科彻斯定理:
任何一个整数的立方都可以写成一连串的连续奇数之和,大家可以编程证明这个定理,知识点不会超出我们现在所讲范围。
====================
=======================
回复D或者d查看目录,对了,我看到有些同学回复第一讲,第二讲…………,在这里我再说一遍,直接回复阿拉伯数字就好,回复10可以直接查看第十讲,回复9查看第九讲……
联系客服