P1236 算24点

题目描述
几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为“算24点”。您作为游戏者将得到4个1~9之间的自然数作为操作数,而您的任务是对这4个操作数进行适当的算术运算,要求运算结果等于24。

您可以使用的运算只有:+,-,,/,您还可以使用()来改变运算顺序。注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(22)/4是合法的,2*(2/4)是不合法的)。下面我们给出一个游戏的具体例子:

若给出的4个操作数是:1、2、3、7,则一种可能的解答是1+2+3*7=24。

输入输出格式
输入格式:
只有一行,四个1到9之间的自然数。

输出格式:
如果有解的话,只要输出一个解,输出的是三行数据,分别表示运算的步骤。其中第一行是输入的两个数和一个运算符和运算后的结果,第二行是第一行的结果和一个输入的数据、运算符、运算后的结果,或者是另外两个数的输出结果;第三行是前面的结果第二行的结果或者剩下的一个数字、运算符和“=24”。如果两个操作数有大小的话则先输出大的。

如果没有解则输出“No answer!”

如果有多重合法解,输出任意一种即可。

注:所有运算结果均为正整数

看到题第一想到的是dfs,就是不知怎么写
就下了一个过百行的模拟

var i1,i2,i3,i4,i5,i6,i7:longint;
    m,n,x,y:longint;
    q:array[1..4]of longint;
    a:array[1..4,1..4,1..4]of int64;
    b:array[1..4]of boolean;
    c:array[1..4,1..4,1..4,1..4,1..4]of int64;
function AC(m,n,x:longint):longint;
var y:longint;
begin
  case x of
    1:y:=m+n;
    2:y:=m-n;
    3:y:=m*n;
    4:if (m<>0) and (n<>0) then if m mod n=0 then y:=m div n else y:=10000000 else y:=10000000;
  end;
  if y>=0 then
  exit(y) else exit(10000000);
end;
function fh(x:longint):char;
begin
  case x of
  1:fh:='+';
  2:fh:='-';
  3:fh:='*';
  4:fh:='/';
  end;
end;
begin
  for i1:= 1 to 4 do read(q[i1]);
  for i1:=1 to 4 do
  for i2:=1 to 4 do
  for i3:=1 to 4 do
  if i1<>i2 then
  a[i1,i2,i3]:=AC(q[i1],q[i2],i3);
  for i1:=1 to 4 do b[i1]:=true;
  for i1:=1 to 4 do
  begin
  b[i1]:=false;
  for i2:=1 to 4 do
  if b[i2] then
  begin
  b[i2]:=false;
  for i3:=1 to 4 do
  if b[i3] then
  begin
  b[i3]:=false;
  for i4:=1 to 4 do
  if b[i4] then
  begin
  for i5:=1 to 4 do
  for i6:=1 to 4 do
  if (a[i1,i2,i5]<>10000000) and (a[i3,i4,i6]<>10000000) then
  begin
    for i7:=1 to 4 do
    begin
      y:=AC(a[i1,i2,i5],a[i3,i4,i6],i7);
      if y=24 then
      begin
          if (q[i1]>q[i2]) or (i5=2) or (i5=4) then
        writeln(q[i1],fh(i5),q[i2],'=',a[i1,i2,i5])
          else
        writeln(q[i2],fh(i5),q[i1],'=',a[i1,i2,i5]);
          if (q[i3]>q[i4]) or (i6=2) or (i6=4) then
        writeln(q[i3],fh(i6),q[i4],'=',a[i3,i4,i6])
          else
        writeln(q[i4],fh(i6),q[i3],'=',a[i3,i4,i6]);
          if (a[i1,i2,i5]>a[i3,i4,i6]) or (i7=2) or (i7=4) then
            writeln(a[i1,i2,i5],fh(i7),a[i3,i4,i6],'=',24)
          else
            writeln(a[i3,i4,i6],fh(i7),a[i1,i2,i5],'=',24);
             exit;
            writeln;
      end;
    end;
  end;
  end;
  b[i3]:=true;
  end;
  b[i2]:=true;
  end;
  b[i1]:=true;
  end;
  for i1:=1 to 4 do b[i1]:=true;
  for i1:=1 to 4 do
  begin
    b[i1]:=false;
    for i2:=1 to 4 do
    if b[i2] then
    begin
      b[i2]:=false;
      for i3:=1 to 4 do
      if b[i3] then
      begin
        for i4:=1 to 4 do
        for i5:=1 to 4 do
                begin
          c[i1,i2,i3,i4,i5]:=AC(a[i1,i2,i4],q[i3],i5);
               end;
      end;
      b[i2]:=true;
    end;
    b[i1]:=true;
  end;
  for i1:=1 to 4 do b[i1]:=true;
  for i1:=1 to 4 do
  begin
    b[i1]:=false;
    for i2:=1 to 4 do
    if b[i2] then
    begin
      b[i2]:=false;
      for i3:=1 to 4 do
      if b[i3] then
      begin
            b[i3]:=false;
        for i4:=1 to 4 do
        if b[i4] then
        begin
          for i5:=1 to 4 do
          for i6:=1 to 4 do
          begin
            if c[i1,i2,i3,i5,i6]<>10000000 then
            begin
              for i7:=1 to 4 do
              begin
                y:=AC(c[i1,i2,i3,i5,i6],q[i4],i7);
                if y=24 then
                begin
                  if (q[i1]>q[i2]) or (i5=2) or (i5=4) then
                  writeln(q[i1],fh(i5),q[i2],'=',a[i1,i2,i5])
                  else
                  writeln(q[i2],fh(i5),q[i1],'=',a[i1,i2,i5]);
                  if (a[i1,i2,i5]>q[i3]) or (i6=2) or (i6=4) then
                  writeln(a[i1,i2,i5],fh(i6),q[i3],'=',c[i1,i2,i3,i5,i6])
                  else
                  writeln(q[i3],fh(i6),a[i1,i2,i5],'=',c[i1,i2,i3,i5,i6]);
                  if (c[i1,i2,i3,i5,i6]>q[i4]) or (i7=2) or (i7=4) then
                  writeln(c[i1,i2,i3,i5,i6],fh(i7),q[i4],'=',24)
                  else
                  writeln(q[i4],fh(i7),c[i1,i2,i3,i5,i6],'=',24);
                                  exit;
                end;
              end;
            end;
                  end;
        end;
            b[i3]:=true;
      end;
      b[i2]:=true;
    end;
    b[i1]:=true;
  end;
  writeln('No answer!');
end.//思路清晰,不想解释

就是懒
在经过老师的一番指点后,终于写出了dfs

const s='+-*/';某位dalao教我的
type arr=array[0..4]of longint;
var i,j,k:longint;
    m,n:longint;
    r:array[0..6,0..4]of longint;
    x,y:longint;
    a:arr;
procedure write_24;//输出
var i,j,k:longint;
begin
  for i:=1 to 3 do
  begin
  writeln(r[i,1],s[r[i,2]],r[i,3],'=',r[i,4]);
  end;
  halt;
end;
procedure sss(m,n:longint;g:arr);
var i,j,k:longint;
    a:array[0..4]of longint;
    x,y,p,o:longint;
begin
  if (m=1) then
  if n=24 then write_24
  else exit;
  for i:=1 to m do a[i]:=-1;
  for i:=1 to m-1 do
  for j:=i+1 to m do
  if (i<>j) then
  begin
  x:=g[i];
  y:=g[j];
  if x<y then
  begin
    p:=x;
    x:=y;
    y:=p;
  end;
  for k:=1 to 4 do
  begin
    r[5-m,1]:=x;
    r[5-m,2]:=k;
    r[5-m,3]:=y;
    r[5-m,4]:=-1;
    case k of//分类
      1:r[5-m,4]:=x+y;
      2:r[5-m,4]:=x-y;
      3:r[5-m,4]:=x*y;
      4:if (y<>0) then if x mod y=0 then r[5-m,4]:=x div y;
    end;
    if r[5-m,4]<>-1 then
    begin
      p:=0;
      for o:=1 to m do
      if (o<>i) and (o<>j) then
      begin
        inc(p);
        a[p]:=g[o];
      end;
      inc(p);
      a[p]:=r[5-m,4];
      a[p+1]:=-1;
      sss(m-1,a[p],a);
    end;
  end;
  end;
end;
begin
  for i:=1 to 4 do read(a[i]);
  sss(4,0,a);
  write('No answer!');//无解
end.

猜你喜欢

转载自blog.csdn.net/sxy__orz/article/details/83025609