博文

39.年龄几何(2005-09-10 15:14:00)

摘要:39.年龄几何
张三、李四、王五、刘六的年龄成一等差数列,他们四人的年龄相加是26,相乘是880,求以他们的年龄为前4项的等差数列的前20项。
*题目分析与算法设计
设数列的首项为a,则前4项之和为"4*n+6*a",前4 项之积为"n*(n+a)*(n+a+a)*(n+a+a+a)"。同时"1<=a<=4","1<=n<=6"。可采用穷举法求出此数列。
*程序说明与注释
#include<stdio.h>
void main()
{
int n,a,i;
printf("The series with equal difference are:\n");
for(n=1;n<=6;n++) /*公差n取值为1~6*/
for(a=1;a<=4;a++) /*首项a取值为1~4*/
if(4*n+6*a==26&&n*(n+a)*(n+a+a)*(n+a+a+a)==880) /*判断结果*/
for(i=0;i<20;i++)
printf("%d ",n+i*a); /*输出前20项*/
}
*运行结果
The series with equal difference are:
2 5 8 11 14 17 20 23 26 29 32 35 38 41 44 47 50 53 56 59......

阅读全文(2508) | 评论:0

38.换分币(2005-09-10 15:12:00)

摘要:38.换分币
用一元人民币兑换成1分、2分和5分硬币,共有多少种不同的兑换方法。
*题目分析与算法设计
根据题意设i,j,k分别为兑换的1分、2分、5分硬币所具有的钱数(分),则i,j,k的值应满足:
i+j+k=100
*程序说明与注释
#include<stdio.h>
void main()
{
int i,j,k,count=1;
printf("There are follwing small exchange plans for 1 Yuan note:\n");
for(i=0;i<=100;i++) /*i为1分硬币钱数,可取值0,1,2...,100*/
for(j=0;j<=100-i;j+=2) /*j为2分硬币钱数,可取0值,2,4,...,100*/
for(k=0;k<=100-i-2*j;k+=5) /*k为5分硬币钱数*/
if(i+j+k==100)
printf(count%4?"%d:1*%d+2*%d+5*%d\t":"%d:1*%d+2*%d+5*%d\n",count++,i,j/2,k/5);
}

......

阅读全文(3170) | 评论:0

37.爱因斯坦的数学题(2005-09-10 15:09:00)

摘要:37.爱因斯坦的数学题
爱因斯坦出了一道这样的数学题:有一条长阶梯,若每步跨2阶,则最最后剩一阶,若每步跨3 阶,则最后剩2阶,若每步跨5阶,则最后剩4阶,若每步跨6阶则最后剩5阶。只有每次跨7阶,最后才正好一阶不剩。请问这条阶梯共有多少阶?
*题目分析与算法设计
根据题意,阶梯数满足下面一组同余式:
x≡1 (mod2)
x≡2 (mod3)
x≡4 (mod5)
x≡5 (mod6)
x≡0 (mod7)
*程序说明与注释
#include<stdio.h>
void main()
{
int i=1; /*i为所设的阶梯数*/
while(!((i%2==1)&&(i%3==2)&&(i%5==4)&&(i%6==5)&&(i%7==0)))
++i; /*满足一组同余式的判别*/
printf("Staris_number=%d\n",i);
}
*运行结果
Staris_number=119
*问题的进一步讨论
此题算法还可考虑求1、2、4、5的最小公倍数n,然后判t(t为n-1)≡0(mod7)是否成立,若不成立则t=t+n,再进行判别,直至选出满足条件的t值。请自行编写程序实现......

阅读全文(3253) | 评论:2

36.百钱百鸡问题(2005-09-10 15:09:00)

摘要:36.百钱百鸡问题
中国古代数学家张丘建在他的《算经》中提出了著名的“百钱买百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何?
*题目分析与算法设计
设鸡翁、鸡母、鸡雏的个数分别为x,y,z,题意给定共100钱要买百鸡,若全买公鸡最多买20只,显然x的值在0~20之间;同理,y的取值范围在0~33之间,可得到下面的不定方程:
5x+3y+z/3=100
x+y+z=100
所以此问题可归结为求这个不定方程的整数解。
由程序设计实现不定方程的求解与手工计算不同。在分析确定方程中未知数变化范围的前提下,可通过对未知数可变范围的穷举,验证方程在什么情况下成立,从而得到相应的解。
*程序说明与注释
#include<stdio.h>
void main()
{
int x,y,z,j=0;
printf("Folleing are possible plans to buy 100 fowls with 100 Yuan.\n");
for(x=0;x<=20;x++) /*外层循环控制鸡翁数*/
for(y=0;y<=33;y++) /*内层循环控制鸡母数y在0~33变化*/
{
z=100-x-y; /*内外层循环控制下,鸡雏数z的值受x,y的值的制约*/
if(z%3==0&&5*x+3*y+z/3==100)
/*验证取z值的合理性及得到一组解的合理性*/
printf("%2d:cock=%2d hen=%2d chicken=%2d\n",++j,x,y,z);
}
}
*运行结果
Follwing are possible plans to buy 100 fowls with 100 Yuan.
1:cock=0 hen=25 chicken=75
2:cock=4 hen=18 chicken=78
3:cock=8 hen=11 chicken=81
4:cock=12 hen=4 chicken=84
*......

阅读全文(7413) | 评论:5

35.素数幻方(2005-06-11 17:26:00)

摘要:35.素数幻方
求四阶的素数幻方。即在一个4X4 的矩阵中,每一个格填 入一个数字,使每一行、每一列和两条对角线上的4 个数字所组成的四位数,均为可逆素数。
*问题分析与算法设计
有了前面的基础,本题应当说是不困难的。
最简单的算法是:采用穷举法,设定4X4矩阵中每一个元素的值后,判断每一行、每一列和两条对角线上的4个数字组成的四位数是否都是可逆素数,若是则求出了满足题意的一个解。
这种算法在原理是对的,也一定可以求出满足题意的全部解。但是,按照这一思路编出的程序效率很低,在微机上几个小时也不会运行结束。这一算法致命的缺陷是:要穷举和判断的情况过多。
充分利用题目中的“每一个四位数都是可逆素数”这一条件,可以放弃对矩阵中每个元素进行的穷举的算法,先求出全部的四位可逆素数(204个),以矩阵的行为单位,在四位可逆素数的范围内进行穷举,然后将穷举的四位整数分解为数字后,再进行列和对角线方向的条件判断,改进的算法与最初的算法相比,大大地减少了穷举的次数。
考虑矩阵的第一行和最后一行数字,它们分别是列方向四位数的第一个数字和最后一个数字,由于这些四位数也必须是可逆素数,所以矩阵的每一行和最后一行中的各个数字都不能为偶数或5。这样穷举矩阵的第一行和最后一行时,它们的取值范围是:所有位的数字均不是偶数或5的四位可逆数。由于符合这一条件的四位可逆素数很少,所以这一范围限制又一次减少了穷举的次数。
对算法的进一步研究会发现:当设定了第一和第二行的值后,就已经可以判断出当前的这种组合是否一定是错误的(尚不能肯定该组合一定是正确的)。若按列方向上的四个两位数与四位可逆数的前两位矛盾(不是其中的一种组合),则第一、二行的取值一定是错误的。同理在设定了前三行数据后,可以立刻判断出当前的这种组合是否一定是错误的,若判断出矛盾情况,则可以立刻设置新的一组数据。这样就可以避免将四个数据全部设定好以后再进行判断所造成的低效。
根据以上分析,可以用伪语言描述以上改进的算法:
开始
找出全部四位的可逆素数;
确定全部出现在第一和最后一行的四位可逆素数;
在指定范围 内穷举第一行
在指定范围内穷举第二行
若第一、第二、三行已出现矛盾,则继续穷举下一个数;
在指定范围内穷举第四行......

阅读全文(2663) | 评论:0

32.要发就发(2005-09-10 15:12:00)

摘要:32.要发就发
“1898--要发就发”。请将不超过1993的所有素数从小到大排成第一行,第二行上的每个素数都等于它右肩上的素数之差。编程求出:第二行数中是否存在这样的若干个连续的整数,它们的和恰好是1898?假好存在的话,又有几种这样的情况?
第一行:2 3 5 7 11 13 17......1979 1987 1993
第二行:1 2 2 4 2 4...... 8 6
*问题分析与算法设计:
首先从数学上分析该问题:
假设第一行中的素数为n[1]、n[2]、n[3]....n[i]、...第二行中的差值为m[1]、m[2]、m[3]...m[j]...。其中m[j]为:
m[j]=n[j+1]-n[j]。
则第二行连续N个数的和为:
SUM=m[1]+m[2]+m[3]+...+m[j]
=(n[2]-n[1])+(n[3]-n[2])+(n[4]-n[3])+...+(n[j+1]-n[j])
=n[j+1]-n[1]
由此题目就变成了:在不超过1993的所有素数中是否存在这样两个素数,它们的差恰好是1898。若存在,则第二行中必有所需整数序列,其和恰为1898,。
对等价问题的求解是比较简单的。
由分析可知,在素数序列中不必包含2,因为任意素数与2的差一定为奇数,所以不必考虑。
*程序与程序注释:
#include<stdio.h>
#include<math.h>
#define NUM 320
int number[NUM]; /*存放不超过1993的全部奇数*/
int fflag(int i);
void main()
{
int i,j,count=0;
printf("there are follwing primes sequences in first row:\n");
for(j=0,i=3;i<=1993;i+=2) /*求出不超过1993的全部奇数*/
if(fflag(i)) number[j++]=i;
for(j--;number[j]>1898;j--) ......

阅读全文(2789) | 评论:0

31.歌德巴赫猜想(2005-09-10 15:12:00)

摘要:31.歌德巴赫猜想
验证:2000以内的正偶数都能够分解为两个素数之和(即验证歌德巴赫猜想对2000以内的正偶数成立)。
*问题分析与算法设计
为了验证歌德巴赫猜想对2000以内的正偶数都是成立的,要将整数分解为两部分,然后判断出分解出的两个整数是否均为素数。若是,则满足题意;否则重新进行分解和判断。
程序中对判断是否为素数的算法进行了改进,对整数判断“用从2开始到该整数的一半”改为“2开始到该整数的平方根”。原因何在请自行分析。
*程序与程序注释
#include<stdio.h>
#include<math.h>
int fflag(int n);
void main()
{
int i,n;
for(i=4;i<=2000;i+=2)
{
for(n=2;n<i;n++) /*将偶数i分解为两个整数*/
if(fflag(n)) /*分别判断两个整数是否均为素数*/
if(fflag(i-n))
{
printf("%14d=%d+%d\n",i,n,i-n); /*若均是素数则输出*/
break;
}
if(n==i) printf("error %d\n",i);
}
}

int fflag(int i) /*判断是否为素数*/
{
int j;
if(i<=1)return 0;
if(i==2)return 1;
if(!(i%2))return 0; /*if no,return 0*/
for(j=3;j<=(int)(sqrt((double)i)+1);j+=2)
if(!(i%j))return 0;
return 1; /*if yes,return 1*/
}

......

阅读全文(2813) | 评论:0

30.求素数(2005-09-10 15:12:00)

摘要:30.求素数
求素数表中1~1000之间的所有素数
*问题分析与算法设计
素数就是仅能衩1和它自身整除的整数。判定一个整数n是否为素数就是要判定整数n能否被除1和它自身之外的任意整数整除,若都不能整除,则n为素数。
程序设计时i可以从2开始,到该整数n的1/2为止,用i依次去除需要判定的整数,只要存在可以整除该数的情况,即可确定要判断的整数不是素数,否则是素数。
*程序与程序注释
#include<stdio.h>
void main()
{
int n1,nm,i,j,flag,count=0;
do{
printf("Input START and END=?");
scanf("%d%d",&n1,&nm); /*输入求素数的范围*/
}while(!(n1>0&&n1<nm)); /*输入正确的范围*/
printf("...........PRIME TABLE(%d--%d)............\n",n1,nm);
if(n1==1||n1==2) /*处理素数2*/
{
printf("%4d",2);
n1=3;count++;
}
for(i=n1;i<=nm;i++) /*判定指定范围内的整数是否为素数*/
{
if(!(i%2))continue;
for(flag=1,j=3;flag&&j<i/2;j+=2)
/*判定能否被从3到整数的一半中的某一数所整除*/
if(!(i%j))flag=0; /*若能整除则不是素数*/
if(flag) printf(++count%15?"%4d":"%4d\n",i);
}
}
*思考题
请找出十个最小的连续自然数,它们个个都是合数(非素数)
......

阅读全文(3540) | 评论:2

29.求具有abcd=(ab+cd)2性质的四位数(2005-09-10 15:12:00)

摘要:29.求具有abcd=(ab+cd)2性质的四位数
3025这个数具有一种独特的性质:将它平分为二段,即30和25,使之相加后求平方,即(30+25)2,恰好等于3025本身。请求出具有这样性质的全部四位数。
*题目分析与算法设计
具有这种性质的四位数没有分布规律,可以采用穷举法,对所有四位数进行判断,从而筛选出符合这种性质的四位数。具体算法实现,可任取一个四位数,将其截为两部分,前两位为a,后两位为b,然后套用公式计算并判断。
*程序说明与注释
#include<stdio.h>
void main()
{
int n,a,b;
printf("There are following number with 4 digits satisfied condition\n");
for(n=1000;n<10000;n++) /*四位数N的取值范围1000~9999*/
{
a=n/100; /*截取N的前两位数存于a*/
b=n%100; /*截取N的后两位存于b*/
if((a+b)*(a+b)==n) /*判断N是否为符合题目所规定的性质的四位数*/
printf("%d ",n);
}
}
*运行结果
There are following numbers with 4 digits satisfied condition:
2025 3025 9801
......

阅读全文(4126) | 评论:0

28.回文数(2005-09-10 15:12:00)

摘要:28.回文数
打印所有不超过n(取n<256) 的其平方具有对称性质的数(也称回文数)。
*题目分析与算法设计
对于要判断的数n,计算出其平方后(存于a),将a的每一位进行分解,再按a的从低到高的顺序将其恢复成一个数k(如n=13,则a=169且k=961),若a等于k则可判定n为回亠数。
*程序说明与注释

原程序好像有错,而且比较费解,现基于原程序修改如下(如果读者还发现错误请提出): #include<stdio.h>
int main(void)
{
    int m[16],n,i,t,count=0;
    long unsigned a,k;
    printf("No. number it's square(palindrome)\n");
    for(n=1;n<256;n++) /*穷举n的取值范围*/
    {
        k=0;t=1;a=n*n; /*计算n的平方*/
       
        for(i=0;a!=0;i++) /*从低到高分解数a的每一位存于数组m[0]~m[16]*/
        {
            m[i]=a%10;//这个是取得a的个位,整个循环合起来就可以取得各个位
            a/=10;
        ......

阅读全文(6414) | 评论:9