问题提出:
设x,y为非负整数,试计算集合M={2^x*3^y|x>=0,y>=0}的元素小于指定整数n的个数,并求这些元素从小到大排序的第m项。
以下给出案例求解的三种设计:
1.穷举求解
设计要点:
集合元素由2的幂与3的幂及其乘积组成,设元素从小到大排序的第k项为f(k)。显然,f(1)=1,f(2)=2。
设置a从3开始递增至n循环,对每一个a(赋值给j),逐次试用2试商,然后逐次试用3试商。
试商后若j>1,说明原a有2,3以外的因数,不属于该序列。
若j=1,说明原a只有2,3的因数,为序列第k项赋值。
由于实施从小到大穷举赋值,所得项无疑是从小到大的序列。
当达到指定的n,退出循环,输出指定项f(m)。
代码如下:
1 #include <stdio.h>
2 void main()
3 {int k,m;
4 long a,j,n,f[1000];
5 printf(" 计算小于n的项数,请指定n: ");
6 scanf("%ld",&n);
7 printf(" 输出序列的第m项,请指定m: ");
8 scanf("%d",&m);
9 f[1]=1;f[2]=2;k=2;
10 for(a=3;a<=n;a++)
11 { j=a;
12 while(j%2==0) j=j/2; // 反复用2试商
13 while(j%3==0) j=j/3; // 反复用3试商
14 if(j==1)
15 { k++;f[k]=a;}
16 }
17 printf(" 幂序列中小于%ld的项数为:%d\n",n,k);
18 if(m<=k)
19 printf(" 从小到大排序的第%d项为:%ld\n",m,f[m]);
20 else
21 printf(" 所输入的m大于序列的项数!\n");
22 }
23
2 void main()
3 {int k,m;
4 long a,j,n,f[1000];
5 printf(" 计算小于n的项数,请指定n: ");
6 scanf("%ld",&n);
7 printf(" 输出序列的第m项,请指定m: ");
8 scanf("%d",&m);
9 f[1]=1;f[2]=2;k=2;
10 for(a=3;a<=n;a++)
11 { j=a;
12 while(j%2==0) j=j/2; // 反复用2试商
13 while(j%3==0) j=j/3; // 反复用3试商
14 if(j==1)
15 { k++;f[k]=a;}
16 }
17 printf(" 幂序列中小于%ld的项数为:%d\n",n,k);
18 if(m<=k)
19 printf(" 从小到大排序的第%d项为:%ld\n",m,f[m]);
20 else
21 printf(" 所输入的m大于序列的项数!\n");
22 }
23