2025年05月01日 星期四 农历 乙巳年(蛇)四月初四

信息学奥赛常考算法——枚举法

发布人:钱翠萍    发布时间:2012-06-10 点击量:3309

    枚举法

用枚举法解决问题的基本思路是依次枚举问题的所有可能解,按照问题的结束条件进行判断,如果满足约束条件则得到一组解,将这个问题不断进行下去,最终得到整个问题的解。(模拟法关心问题怎么做,而枚举法关心当前的可能解是不是

用枚举法解决问题,首先需要知道解的范围并能以合适的方法列举,其次要对问题的约束条件进行精确地描述,这两个环节有一个疏漏就有可能丢失正确解或多出错误解。枚举法虽然使用起来很容易,但对于大量数据,枚举法的效率是很低的。

典型例题:

【例题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】数字三角形。

12···99个数排成下列形状的三角形:

                    a

                 b     c

             d            e

         f      g     h      i

其中:a~i分别表示12···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.