大师匈觉得C语言博大精深,一个合格的程序员不仅要有严密的逻辑思维,精通MCU啊,操作系统啊,各种行业相关的听起来很高大上的东西,而且要有数学思维,敏锐的嗅觉出色的debug能力,混迹几年,发现一些很基础的数学思维竟然也开始僵化了;如不等式,如排列组合的各种灵活应用,可能平时用的少,但是有一些空闲,多练习一些,让自己多思考一下,不至于让自己的脑袋逐渐僵化。
第一题:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
先不用程序实现,直接去算,有多少种,如果你还记得高中的排列组合,那么结果很显然就是A(3,4),就是432 = 24种。
看到这里的同学都有没有想到这个呢。
那么如果再加一个条件,24个组合里面不相同的组合有多少种,这里的不相同指的是乱序的不同。比如123和321它是一个组合。
用排列组合公式计算就是4种,A(3,4)/A(3,3) = 4;
上面是数学的算法,计算有多少种;
那么用C语言程序去排列它们,就非常简单了;代码如下:
#include"stdio.h"
void main()
{
int arry[4] = { 1,2,3,4};
int i = 0,j = 0,k = 0;
int number = 0;
for(i = 0;i < 4;i++)
{
for(j = 0;j < 4;j++)
{
for(k = 0;k < 4;k++)
{
if((i != j)&&(i != k)&&(j != k))
{
printf(" %d ",arry[i]);
printf(" %d ",arry[j]);
printf(" %d\n",arry[k]);
number++;
}
}
}
}
printf("number = %d\n",number);
} 在这里插入代码片
第二题:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
第一眼看过去。大家必然会在脑海里形成俩个公式:
1、x+100 = nn;
2、x+100+168 = mm;
接下来我们要怎么算呢?很显然这有三个未知数,但只有俩个方程式,必然不可能直接求出答案;
这里要利用数学的不等式思想,没有不等式创造不等式;
那么mm - nn = 168;m和n的相差为1,它俩的差值最小,如果差值为1的m,n的平方相减刚好大于168,那么就是m和n的上限,我们就可以去穷举了;
我们也可以用类似的办法知道它的下限,就是mm+nn这俩个肯定大于168的,那么n最小为1,我们可以知道m的最小值是13;这样又进一步缩小了范围;
下面就是代码了:不过这段代码没有去做下限。。。
int main()
{
int m,n,i,j,x;
for(m = 1,n = 0;m*m- n*n < 169;m++,n++);
printf("m = %d\n",i = m);
printf("n = %d\n",j = n);
for(m=2;m<i+1;m++)
{
for(n=1;n<j+1;n++)
{
if((m*m - n*n) == 168)
{
printf("x = %d\n",n*n - 100);
}
}
}
}
我这里在还有一个解题方案比上面这个更好一些,我把代码贴出来:
int main()
{
int i,j,m,n,x,q;
for(i=2;i<85;i+=2)//由于i在分子部分,所以不能为0.不然直接死机
{
if(168%i == 0)
{
j = 168/i;
if(i > j && (i+j) %2 == 0 && (i-j)%2 == 0)
{
m = (i + j)/2;
n = (i - j)/2;
q = m*m - n*n;
if(q == 168)
{
x = n*n - 100;
printf("x = %d\n",x);
}
}
}
}
}
延续第一种解法:
1、x+100 = nn;
2、x+100+168 = mm;
3、mm - nn = 168 -> (m+n)(m-n) = 168 ,我们设i = (m+n),j = (m-n);那么i和j 至少有一个为偶数;
4、然后再进行推导,m = (i+j)/2,n = (i-j)/2,所以(i+j)或者(i-j)必然为偶数,所以i和j要么都是偶数要么都是奇数,我们根据第三步得知,至少有一个偶数,所以i和j都是偶数;
4、ij = 168,如果j = 2,那么i 肯定是最大的;所以 i 的最大值就是84;
5、我们就从2开始穷举i,知道i = 2,那么必然能求出j,m,n,x,我们就知道 找到我们想要的值;
OVER 。。。。