★ 枚举法
用枚举法解决问题的基本思路是依次枚举问题的所有可能解,按照问题的结束条件进行判断,如果满足约束条件则得到一组解,将这个问题不断进行下去,最终得到整个问题的解。(模拟法关心问题“怎么做”,而枚举法关心当前的可能解“是不是”)
用枚举法解决问题,首先需要知道解的范围并能以合适的方法列举,其次要对问题的约束条件进行精确地描述,这两个环节有一个疏漏就有可能丢失正确解或多出错误解。枚举法虽然使用起来很容易,但对于大量数据,枚举法的效率是很低的。
典型例题:
【例题1】四个人中有一个人是小偷,现在警察得到了这样的证词:
A说:不是我。
B说:是C。
C说:是D。
D说:他胡说。
已知三个人说的是真话,一个人说的是假话。现在要根据这些信息,确认小偷是谁?
program xiaotou;
var n:integer;t:char;
begin
for t:=‘A’ TO ‘D’ do
begin
n:=ord(t’A’)+ord(t=‘C’)+ord(t=‘D’)+ord(t’D’);
if n=3 then writeln(‘this man is’,t);
end;
end.
【例题2】数字三角形。
把1,2,···,9共9个数排成下列形状的三角形:
a
b c
d e
f g h i
其中:a~i分别表示1,2,···,9中的一个数字,并要求同时满足下列条件:
⑴a
⑵b
⑶a+b+d+f=f+g+h+i=i+e+c+a=p
程序要求:根据输入的边长之和p,输出所有满足上述条件的三角形的个数及其中的一种方案。
program shuzisanjiao;
var a,b,c,d,e,f,g,h,i,k,p,sum:integer;
bb:array[1..100] of byte;
begin
readln(p);
sum:=0;
for a:=1 to 7 do
for b:=1 to 8 do
for c:=1 to 8 do
for g:=1 to 8 do
for f:=a+1 to 8 do
for i:=f+1 to 9 do
begin
d:=p-a-b-f;
if d
h:=p-f-g-i;
if h
e:=p-a-c-i;
if e
fillchar(bb,sizeof(bb),0);
bb[a]:=1;
bb[b]:=1;
bb[c]:=1;
bb[d]:=1;
bb[e]:=1;
bb[f]:=1;
bb[g]:=1;
bb[h]:=1;
bb[i]:=1;
for k:=1 to 9 do
if bb[k]=0 then break;
if bb[k]=1 then
begin
inc(sum);
writeln(a:3,b:3,c:3,d:3,e:3,f:3,g:3,h:3,i:3);
end;
end;
writeln(sum);
end.