穷举法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第16章 穷举算法与实验
穷举方法是基于计算机特点而进行解题的思维方法。
一般是在一时找不出解决问题的更好途径(即从数学上找不到求解的公式或规则)时,可以根据问题中的的部分条件(约束条件)将所有可能解的情况列举出来,然后通过一一验证是否符合整个问题的求解要求,而得到问题的解。
这样解决问题的方法我们称之为穷举算法。
穷举算法特点是算法简单,但运行时所花费的时间量大。
因此,我们在用穷举方法解决问题时,应尽可能将明显的不符合条件的情况排除在外,以尽快取得问题的解。
虽然穷举法效率并不高,但是适应一些没有明显规律可循的问题的解决。
因为穷举算法就是从所有可能的情况中搜索正确的答案,所以一般可按如下步骤: 第1步: 对于一种可能的情况,列举出来并计算其结果;
第2步:判断结果是否满足要求,如果不满足则执行第1步来搜索下一个可能的情况,如果满足要求,则表示寻找到一个正确的答案,执行下一步操作,如寻找其他正确(合适)的答案或者中断循环。
16.1三角形数问题
16.1.1 问题描述
将 ,F ,E ,D ,C ,B ,A 这六个变量排成如图所示的三角形,这六个变量分别取[1,6]上的
整数,且均不相同。
求使三角形三条边上的变量之和相等的全部解。
如图就是一个解。
A 6
B C 3 1
D F 2 4
E 5
16.1.2 问题分析
程序引入变量123456,,,,,i i i i i i ,代表,F ,E ,D ,C ,B ,A 并让它们分别顺序取1至6的正整数,在它们互不相同的前提条件下,测试由它们排成的如图所示的三角形三条边上的变量之和是否相等,如相等即为一种满足要求的排列,把它们输出。
当这些变量取尽所有的组合后,程序就可得到全部可能的解。
细节见下面的程序。
【程序1】
%穷举法解三角形数 for i1=1:6 for i2=1:6 if i1==i2 continue;
end
for i3=1:6
if i1==i3 || i2==i3
continue;
end
for i4=1:6
if i1==i4 || i2==i4 || i3==i4
continue;
end
for i5=1:6
if i1==i5 || i2==i5 || i3==i5 || i4==i5
continue;
end
for i6=1:6
if i1==i6 || i2==i6 || i3==i6 || i4==i6 || i5==i6
continue;
end
if i1+i2+i4==i1+i3+i6 && i1+i2+i4==i4+i5+i6
fprintf ('%6d\n',i1) ;
fprintf ('%4d%4d\n',i2,i3) ;
fprintf ('%2d%4d%4d\n\n',i4,i5,i6) ;
end
end
end
end
end
end
End
16.1.3 问题讨论
按穷举法编写的程序通常不能适应变化的情况。
如问题改成有9 个变量排成三角形,每条边有4 个变量的情况,程序的循环重数就要相应改变,而且程序的复杂程度大大增加。
对一组数穷尽所有排列,还有更直接的方法。
将一个排列看作一个长整数,则所有排列对应着一组整数。
将这组整数按从小到大的顺序排列排成一个整数,从对应最小的整数开始。
按数列的递增顺序逐一列举每个排列对应的每个整数,这能更有效地完成排列的穷举。
从一个排列找出对应数列的下一个排列可在当前排列的基础上作部分调整来实现。
倘若当前排列为1,2,4,6,5,3,并令其对应的长整数为124653。
要寻找比长整数124653 更大的排列,可从该排列的最后一个数字顺序向前逐位考察,当发现排列中的某个数字比它前一个数字大时,如本例中的6 比它的前一位数字4 大,这说明还有对应更大整数的排列。
但为了顺序从小到大列举出所有的排列,不能立即调整得太大,如本例中将数字6 与数字4 交换得到的排列126453 就不是排列124653 的下一个排列。
为了得到排列124653 的下一个排列,应从已经考察过的那部分数字中选出比数字大,但又是它们中最小的那一个数字,比如数字5,与数字4 交换。
该数字也是从后向前考察过程中第一个比4 大的数字。
5 与4 交换后,得到排
列125643。
在前面数字1,2,5 固定的情况下,还应选择对应最小整数的那个排列,为此 还需将后面那部分数字的排列顺序颠倒,如将数字6,4,3 的排列顺序颠倒,得到排列1, 2,5,3,4,6,这才是排列1,2,4,6,5,3 的下一个排列。
按以上想法编写的程序如下。
【改进的程序1’】
%穷举法 解三角形的其他方法 a=1:6;%构建序列数组
while ~all(a==6:-1:1) %判断是否达到最大的数列,即654321
if a(1)+a(2)+a(4)==a(1)+a(3)+a(6) && a(1)+a(2)+a(4)==a(4)+a(5)+a(6) fprintf ('%6d\n',a(1)) ;
fprintf ('%4d%4d\n',a(2),a(3)) ;
fprintf ('%2d%4d%4d\n\n',a(4),a(5),a(6)) ; end
for i1=6:-1:2
if all(a(i1)-a(i1-1)>0) %如果遇到比较大得数则开始替换 zc=7;
for j1=i1:6 %寻找一个最小的但大于比较数的且在考察区域的值进行交换 if a(j1)>a(i1-1) && a(j1)<zc zc=a(j1);%zc 用于临时存储那个数 j2=j1; end end
a(j2)=a(i1-1); %替换 a(i1-1)=zc; %替换
a(i1:end)=sort(a(i1:end)); %重排序,交换后的考察区域按降序排列 break; end end end
从上述问题解决的方法中,最重要的因素就是确定某种方法来确定所有的候选解。
下面 再用一个示例来加以说明。
16.2 背包问题
16.2.1问题描述
有不同价值、不同重量的物品n 件,求从这n 件物品中选取一部分物品的选 择方案,使选中物品的总重量不超过指定的限制重量,但选中物品的价值之和最大。
16.2.2 问题分析
设n 个物品的重量和价值分别存储于数组] w[和] v[中,限制重量为tw 。
考虑一个n 元组()110,...,,-n x x x ,其中0 i x =表示第i 个物品没有选取,而1i x =则表示第i 个物品被选
取。
显然这个n 元组等价于一个选择方案。
用枚举法解决背包问题,需要枚举所有的选取方案,而根据上述方法,我们只要枚举所有的n 元组,就可以得到问题的解。
显然,每个分量取值为0 或 1的n 元组的个数共为n 2个。
而每个n 元组其实对应了一个长度为n 的二进制数,且这些二进制数的取值范围为1-20n
→。
因此,如果把
1-20n →分别转化为相应的二进制数,则可以得到我们所需要的n 2个n 元组。
【算法2】
%背包算法,这个算法用函数实现
function [value pai]=beibao(w,v,tw,n) b=zeros(1,n);%用于存储二进制数 value=0;%初始化 for i1=0:2^n-1 for j1=1:n
b(j1)=mod(i1,2); i1=floor(i1/2); end
if sum(w.*b)<=tw && sum(b.*v)>value%满足重量限制 value=sum(b.*v);pai=b; end end end
16.3 边长为整数、周长为定数的三角形个数。
16.3.1问题描述
输入绳子的长度n ,将该绳子分成三段,每段的长度为正整数,输出由该三段绳子组成的三角形个数。
16.3.2算法分析
没有公式直接求出三角形的个数,所以程序只能采用穷举法,一一验证范围内的数是否能构成三角形,若是则累计。
假设三角形的三个边分别是123,,i i i 。
并设32i i >(防止重复的现象,如2,2,3与3,2,2重复其实是一个三角形),且123,,i i i 均为大于1的整数,312i n i i =--。
由三角形三边的性质知:123i i i +>,132i i i +>,231i i i +>。
当满足以上条件均满足时,可以判断这时的123,,i i i 可以构成一个三角形,计数加一。
根据以上编写的程序如下: 【程序3】
%分隔绳子的算法
n=input('the length of string is ');
num=0;
for i1=1:n-2 %三个边长的穷举 for i2=i1:n-1-i1 i3=n-i1-i2;
if i1+i2>i3 && i1+i3>i2 && i2+i3>i1 && i3>=i2 num=num+1;%计数加一
fprintf('the num is %d %d %d\n',i1,i2,i3); end end end
fprintf('长度为 %d 的绳子分成三段可以组成 %d 个三角形\n',n,num);
16.4 一元三次方程的根
16.4.1 问题描述:
有形如:3
2
a*x *x *x 0b c d +++= 这样的一个一元三次方程。
给出该方程中各项的系数(d ,c ,b ,a 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。
要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
提示:记方程()0f x =,若存在2个数1x 和2x ,且12x x <,()()120f x f x *<,则在
()12,x x 之间一定有一个根。
样例:
输入:1 -5 -4 20 输出:-2.00 2.00 5.00
16.4.2 问题分析:
首先我们使用一个循环因子x ,x 的范围从-100到100,每次增加0.01,这样我们可以把x 当作这个方程可能的根进行测试,记方程()0f x =,若存在这样的x ,
()()0.010f x f x *-<,则x 是方程的一个根。
先求出这个的第一个根,然后用同样的方
法,计算出另外的根,并且使其满足根与根之差的绝对值>=1,最后按顺序输出结果。
根据以上思想编写的程序如下: 【程序4】:
%ax3+bx2+cx+d=0 这样的一个一元三次方程的解的情况 function x=sol(a,b,c,d)
% a=1 ; b=-5 ; c= -4 ; d= 20;%测试用的数据 i=1;
x=zeros(1,3); for i1=-100:0.01:100
if (power(i1, 3)*a + power(i1, 2)*b + c*i1 +d)*(power(i1+0.01, 3)*a + ... power(i1+0.01, 2)*b + c*(i1+0.01) +d)<0
if i==2 && abs(x(i)-x(i-1))>=1 || i==3 && abs(x(i)-x(i-2))>=1 && ... abs(x(i)-x(i-1))>=1 || i==1 x(i)=i1+0.01; end i=i+1; end end
fprintf('方程的解为 %.2f %.2f %.2f \n',x); end
16.5 学校名次
16.5.1问题描述
有A ,B ,C ,D ,E ,所学校。
在一次检查评比中,已知E 校肯定不是第2名或第3名,他们互相进行推测。
A 校有人说,E 校一定是第1名;B 校有人说,我校可能是第2名;C 校有人说,A 校最差;D 校有人说,C 校不是最好的;E 校有人说,D 校会获第1名。
结果第1名和第2名学校的人猜对了。
编程指出这5所学校的名次。
16.5.2 问题分析
本题是一个逻辑判断题,一般的逻辑判断题都可以采用穷举法进行解决。
此题的难点在于确定判断条件。
我们设立逻辑变量pai 来描述这一条件,主要有两个条件:“E 校肯定不是第2名或第3名”与“只有第1名和第2名的学校的人猜对”,后一条件要判断:1)学校获得的排名情况是怎样的?2)取得第一名和第二名的学校的预测结果与事实是否相符合?
我们对5所学校所得名次的所有可能情况进行穷举。
在每种情况中,为了防止不同学校取相同的名次,设立了逻辑数组pai ,[]1,pai J K =表示J 校取第K 名,并使[]1,:pai 中没有相同的数,同时,[]pai 2:6,j 表示J 校的预测情况,[],pai I J K =表示在J 校的预测中I 校为第K 名,若0K =,则表示没有对其预测。
然后我们对各校的可能取得的名次进行穷举,并取排名前二位的预测情况进行分析对比,若发现E 校是第2名或第3名或者第一、二名的预测与当前的情况不相符,则认为当前这种情况是不合理的,继续下一个循环,直到满足所有条件后输出结果。
根据以上的思想编写的程序如下: 【程序5】
%学校排名问题
pai=zeros(6,5);% pai 的第一行用于存放排名,第二到六行用于存储假设方案。
0表示无假设,1,2。
%
5表示假设排名,6表示不为第一名,第1.2..5列分别表示A ,B 。
E 的假设
pai(6,1)=1;% A 假设E 是第一 pai(3,2)=2;% B 假设B 是第二 pai(2,3)=5;% C 假设A 是最后 pai(4,4)=6;% D 假设A 不是第一 pai(5,5)=1;% E 假设D 是第一 for a=1:5
for b=1:5 for c=1:5 for d=1:5 for e=1:5
if a==b || b==c || a==c || a==d || b==d || c==d || a==e || b==e || c==e ... || d==e || e==2 || e==3
continue; end
pai(1,:)=[a,b,c,d,e]; [pa x]=sort(pai(1,:));%排序
yuce=[pai(2:end,x(1)),pai(2:end,x(2))];%提取第一,第二名的预测信息 for i1=1:5
if yuce(i1,1)~=0 && yuce(i1,1)~=pai(1,i1) || yuce(3,1)==6 &&... pai(1,3)==1||
yuce(i1,2)~=0
&&
yuce(i1,2)~=pai(1,i1)
||
yuce(3,2)==6
&&
pai(1,3)==1 %第一,二名预测不准确则退出循环 判断C 不为第一名可C 又是第一名时,退出循环
break; end if i1==5
fprintf('a=%d,b=%d,c=%d,d=%d,e=%d\n',a,b,c,d,e); end end end end end end
end
运行结果:
a=5 b=2 c=1 d=3 e=4
16.6 阿姆斯特朗数。
16.6.1问题描述
编一个程序找出所有的三位数到七位数中的阿姆斯特朗数。
阿姆斯特朗数也叫水仙花数,它的定义如下:若一个n 位自然数的各位数字的n 次方之和等于它本身,则称这个自然数为阿姆斯特朗数。
例如5)*5*53*3*31*1*1153(153++=是一个三位数的阿姆斯特朗数,8208则是一个四位数的阿姆斯特朗数。
16.6.2问题分析
列举所有的情况,并且用除10求余的方法提取一个n 位数的每一位数的数值,若各位数字的n 次方之和等于它本身,则找到一个阿姆斯塔朗数,打印出该结果,否则则跳过这次
循环。
【程序6】
%寻找阿姆斯特朗数
for cur=100:10000000 %从三位数到七位数,cur 存储当前数 dig=zeros(1,8);%digit 存储某一个数每一位的值 cur1=cur; for i1=1:8
dig(i1)=mod(cur,10);%提取第i1位 cur=floor(cur/10); if dig(i1)==0 c=c+1; end if cur==0 break; end end
if sum(power(dig(1:i1),i1))==cur1 fprintf(' %07d \n',cur1); end
end
运行结果:
0000153 0000370 0000371 0000407 0001634 0008208 0009474 0054748 0092727 0093084 0548834 1741725 4210818 9800817 9926315 ...
16.7 邮票面值。
16.7.1 问题描述:
邮局发行一套票面有四种不同值的邮票,如果每封信所贴邮票张数不超过三枚,存在整数R,使得用不超过三枚的邮票,可以贴出连续的整数1、2、3,... ,R来,找出这四种面值数,使得R值最大。
16.7.2 问题分析
可能的解是有限的,可用穷举法。
设四种邮票的面值分别为: D , C , B ,A ,可以设D C B A <<<,且必有1A =,再分别给D C,B,足够大的选择区间2A *3B A +<<、2B *3C B +<<、2C *3D C +<<。
每一种情况下,带入一个值R 表示能贴到的最大整数,每一种情况刚开始的时候1R =。
取
D , C , B ,A 的数量分别为1234,,,i i i i ,若存在能够在三张之内凑成R ,且不多于三张(1234***i a i b i c i d r *+++=并且12343i i i i +++≤),则认为这种情况下可以贴到整数R ,将R 加1后继续考察,直到1R +时不再满足判定条件,若此时凑成R 的邮票种类中有D 的构成(4i 不
等于0),则打印出这种邮票的组合以及能贴到的最大的R 值。
【程序7】
%邮票面值问题
a=1;%若满足1,则a只能为一
ji=0;j=0;%状态量
for b=2:3*a+1 %给b一个足够大的值选择区间
for c=b+1:3*b+1%给c一个足够大的值选择区间
for d=c+1:3*c+1%给c一个足够大的值选择区间
for r=1:3*d %简单推理即可发现最大面值R不会超过3*d
ji=1;
for i1=0:3
for i2=0:3-i1
for i3=0:3-i1-i2
for i4=0:3-i1-i2-i3
if i1*a+i2*b+i3*c+i4*d==r
ji=0;j=i4;
end
end
end
end
end
if ji
if j
fprintf('%2d %2d %2d %2d,%2d\n',a,b,c,d,r-1);
end
break;
end
end
end
end
end
程序运行后,部分输出结果如下:
1 2 3 5,13
1 2 3 6,15
1 2 3 7,17
1 2 3 8,14
1 2 3 9,15
.....
1 4 6 14,16
1 4 6 15,23 1 4 7 9,23
16.8方格填数
16.8.1问题描述
如图所示的8个格子中放入1~8八个数字,使得相邻的和对角线的数字之差不为1。
编程找出所有放法。
b1 b2 b3 b4 b5
b6 b7
b8
16.8.2问题分析
可能的解是有限的,可用穷举法。
构建一个数列b ,其中包含八个元素128,b b b ,使他们分别取1,28 ,且相互之间不相等,对于每一种情况,判断相邻的和对角线的数字之差是否为1,若都不是则打印出结果,否则跳过此次循环。
【程序8】
%方格填数 b=1:8;
while ~all(b==8:-1:1)
if all(abs(b(2:4)-b(1))-1) &&all(abs(b(1:7)-b(3))-1) && all(abs(b(2:8)-b(6))-1) && all(abs(b(5:7)-b(8))-1) if all(abs([b(3) b(5) b(6)]-b(2))-1) && all(abs([b(3) b(7) b(6)]-b(4))-1) if all(abs([b(7) b(5)]-b(8))-1)
fprintf('%4d\n%2d%2d%2d\n%2d%2d%2d\n%4d\n\n',b); end end end for i1=8:-1:2
if all(b(i1)-b(i1-1)>0) zc=9; for j1=i1:8
if b(j1)>b(i1-1) && b(j1)<zc zc=b(j1);
j2=j1; end end
b(j2)=b(i1-1); b(i1-1)=zc; b(i1:end)=sort(b(i1:end)); break; end end End
16.9:4皇后问题
16.9.1问题描述
在4×4的棋盘上安置4个皇后,要求任意两个皇后不在同一行、不在同一列、不在同一对角线上,输出所有的方案。
16.9.2问题分析
1) 本题是一个搜索问题,搜索范围 4*4,找出符合条件的方案;
2)方案必须满足的条件:任意两个不在同一行、同一列和同一对角线。
首先假设有一个虚拟的4*4的棋盘,由于任意两个皇后不在同一行,所以每一列均有一个皇后,假设每个皇后在该列的第128,i i i 行,对于128,i i i 进行遍历,已知它们的范围是1到4,且对于每一种情况如果有任意两个皇后不在同一行和同一对角线。
那么我们认为满足条件,则输出这种情况。
提示:当两个皇后处于同一行或者同一对角线时,他们所在的行数的差绝对值等于列数的差的绝对值或者0.
可用穷举算法的代码实现方法 【程序9】
%皇后问题
for i1=1:4 %i1.。
表示皇后的位置 for i2=1:4 for i3=1:4 for i4=1:4
hh=zeros(4,4);%用于模拟棋盘
hh(1,i1)=1; % 1表示此处有皇后 由于分列,所以不再同一列 hh(2,i2)=1; hh(3,i3)=1; hh(4,i4)=1;
if i1==i2 || i1==i3 || i1==i4 || i2==i3 || i2==i4 || i3==i4 % 判断是否在同一行 continue;
end
if abs(i1-i2)==1 || abs(i1-i3)==2 || abs(i1-i4)==3 || abs(i2-i3)==1 || abs(i2-i4)==2 ...
|| abs(i3-i4)==1 % 判断是否在一条对角线上
continue;
end
disp(hh);%打印棋盘,1为皇后
end
end
end
End
16.10巧妙填数
16.10.1问题描述:
将1~9这九个数字填入九个空格中。
每一横行的三个数字组成一个三位数。
如果要使第二行的三位数是第一行的两倍,第三行的三位数是第一行的三倍,应怎样填数。
如图所示。
1 9 2
3 8 4
5 7 6
16.10.2问题分析
可能的解是有限的,可用穷举法。
建立一个3*3的数组,每个元素的取值均在1到9之间,且互不相同,若满足每一横行的三个数字组成一个三位数。
如果要使第二行的三位数是第一行的两倍,第三行的三位数是第一行的三倍,则输出结果。
【程序10】
a=1:9;%构建序列数组
while ~all(a==9:-1:1) %判断是否达到最大的数列,即987654321
if sum(2*a(1:3).*[100 10 1])==sum(a(4:6).*[100 10 1]) && sum(3*a(1:3).*[100 10 1])…
= =sum(a(7:9).*[100 10 1] )
disp(a);
end
for i1=9:-1:2 %此循环用于实现穷举算法,详细见本章改编程序1’
if all(a(i1)-a(i1-1)>0)
zc=10;
for j1=i1:9
if a(j1)>a(i1-1) && a(j1)<zc
zc=a(j1);
j2=j1;
end
end
a(j2)=a(i1-1);
a(i1-1)=zc; a(i1:end)=sort(a(i1:end)); break; end end End
16.11数塔问题
16.11.1问题描述
有形如下图所示的数塔,从顶部出发,在每一结点可以选择向左走或是向右走,一直走到底层,要求找出一条路径,使路径上的数值的和最接近零。
16.11.2问题分析
可能的解是有限的,可用穷举法。
我们发现在上一层与对应下一层的有两条路径,即只有两种选择方案即左与右,假设某数位于第i 行的第k 位,则其向下的选择方案有左与右,当选择左时,第1i +行的对应数的位置仍是第0k +位,当选择向右时,其1i +行的对应位置是1k +位。
因此我们可以将每层之间的路径选择方案简化为0与1(左或者右)。
假设一共有j 层的话,那么就有1j -种0/1选择方案,看做对应离散的二进制码,然后转化为相应连续的十进制码,方便进行穷举运算。
其中在第k 行选择的数的位置是前1k -个二进制码的和加1。
比如:共有4行,十进制为5,则转化为对应的三位(对应三个路径选择方案)的二进制为101(右 左 右):第一行选择的数的位置是第1位,第二行选择的数的位置是第2位,第三行选择的数的位置是第2位,在第四行选择的数的位置是第3位。
根据以上思想,以连续的十进制进行穷举,转化为对应离散的二进制后提取各种情况下的路径选择信息,分析出各种情况并取最值,然后输出结果。
根据以上思想编写的程序如下: 【程序11】 %寻路问题
n=input('输入数塔的层数n(正整数n<=20) ');
st=zeros(n);%创建一个数塔,用于存储数据,0表示没有数据 for i1=1:n
for j1=1:i1
fprintf('输入第%d 行第%d 个数据(且数字的绝对值不超过1000000) ',i1,j1); st(i1,j1)=input(' ');
end
end
sz=inf;%用于存储最终的数值,inf表示无限大
ls=zeros(1,n(1)-1);
lj=zeros(1,n(1)-1);%用于存储最终路径
for i1=0:2^n-1%每一次选择向左则是0,向右则是1,将0与1的集合转换为10进制的ss=st(1,1);%临时存储数据值
for j1=1:n(1)-1
ls(j1)=mod(i1,2);%提取并存储i1中携带的二进制路径信息
i1=floor(i1/2);
end
k=1;%用于二进制路径值到实际路径选择的转化。
for j1=1:n(1)-1 %路径有传递性,上下之间有一定的联系
k=k+ls(j1);%很据图纸发现,向左走时下一层路径坐标不变,向右是路径坐标加一
ss=ss+st(j1+1,k);
end
if ss<sz
sz=ss;
lj=ls;
end
end
fprintf(' %d ',st(1,1));
for i1=1:n(1)-1
if lj(i1)==1
fprintf(' 向右选择');
else
fprintf(' 向左选择');
end
fprintf('%3d ',st(i1+1));
end
fprintf(' 最终的最小值是%d \n',sz);
16.12 习题
1、有一群鸡和一群兔,它们的只数相同,它们的脚数都是三位数,且这两个三位数的数字分别是0,1,2,3,4,5。
问鸡和兔的只数各是多少?它们的脚数各是多少?
2、有一个三位数,个位数字比百位数字大,而百位数字又比十位数字大,并且各位数字之和等于各位数字相乘之积,求此三位数。
分析:如果以A、B、C分别表示这个三位数的百位、十位和个位数字,由题意知B<A<C,由此做穷举
3、蜘蛛有8条腿,蜻蜓有6条腿和2对翅,蝉有6条腿和1对翅。
三种虫子共18共,共有118条腿和20对翅。
问每种虫子各几只?
4、甲、乙两数的和为168,甲数的八分之一与乙数的四分之三的和为76,求甲、乙两数各是多少?
5、我国古代数学问题:1兔换2鸡,2兔换3鸭,5兔换7鹅。
某人用20只兔换得鸡、鸭、鹅共30只,问其中鸡、鸭、鹅各几只?
6、假定小鸡每只5角,公鸡每只2元,母鸡每只3元。
现在100元要求买100只鸡,编程列出所有可能的购鸡方案。
7、猴子吃桃子。
小猴在一天摘了若干个桃子,当天吃掉一半多一个;第二天接着吃了剩下的桃子的一半多一个;以后每天都吃尚存桃子的一半零一个,到第7天早上要吃的时候发现只剩下一个了,问小猴子那天总共摘下了多少桃子?
8、 求这样的四位数abcd ,使abcd dcba ⨯=4,即交换数位后是原数的4倍
算法提示:穷举法(i=1000 to 9999/4)(以下是VBS 示例:)
9、在99⨯的格子里,沿着线路走,从左上角开始,每步只能向右、向下方向走,走到右下角,共有多少种走法?
算法提示:1,杨辉三角数,2.回溯法 把100最多可拆成哪些正整数的平方和? 11、求1000前五个质数。
For i=1000 to 9999/4
IF StrReverse(i*4)=CStr(i) Then ss=ss & i & "," Next
MsgBox ss。