24点

本文介绍了经典的24点游戏及其解法,通过递归枚举所有可能的运算组合,实现对给定四个数字进行加减乘除运算以达到24的目标。提供了两种不同的算法实现思路,包括详细的伪代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【问题描述】

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

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

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

【输入】

只有一行,四个19之间的自然数。

【输出】

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

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

【样例】

point24.in    

1 2 3 7

point24.out

 2+1=3

7*3=21

21+3=24

这道题,有点麻烦。。。。。。。但鉴于今年的最后一道题,所以我个人觉得还是有写一下的必要。。。。

但其实,我也是个懒人呐。。。。。这道题,直接拷标程。。。。。(我以前写的找找不到了);

type arr=array [1..4] of integer;
var i,result,n,len:integer;
    d:arr;
    r:array [1..3,1..4] of integer;
procedure print;
 var i,j:integer;
  begin
   assign(output,'point.out'); rewrite(output);
   for i:=1 to 3 do
     begin
      for j:=1 to 3 do
        if j<>2 then write(r[i,j])
          else case r[i,j] of
                  1:write('+');
                  2:write('-');
                  3:write('*');
                  4:write('/')
                end;
       writeln('=',r[i,4])
    end;
  close(output);
end;
procedure try(k:integer;var d:arr);
  var a,b,i,j,l,t:integer;
    e:arr;
  begin
  if k=1 then
    if d[1]=24 then begin print;halt end
    else
  else    begin
       for i:=1 to k-1 do
        for j:=i+1 to k do
         begin
           a:=d[i]; b:=d[j];
           if a<b then begin t:=a;a:=b;b:=t end;
           t:=0;
           for l:=1 to k do if (l<>i) and (l<>j) then begin t:=t+1;e[t]:=d[l] end;
           r[5-k,1]:=a;
           r[5-k,3]:=b;
           r[5-k,4]:=-1;
           for l:=1 to 4 do
            begin
             case l of
               1:r[5-k,4]:=a+b;
               2:r[5-k,4]:=a-b;
               3:r[5-k,4]:=a*b;
               4:if b<>0  then if a mod b=0 then r[5-k,4]:=a div b
             end;
            r[5-k,2]:=l;
            if r[5-k,4]<>-1 then
                 begin
                  e[t+1]:=r[5-k,4];
                  try(k-1,e)
                 end
           end
        end
     end;
end;
begin
  assign(input,'point.in');reset(input);
  for i:=1 to 4 do read(d[i]);
  close(input);
  try(4,d);
  assign(output,'point.out');rewrite(output);
  writeln('No answer!');
  close(output);
end.


同时,想到了另一道题,“速算游戏”,类似的,也写过。。。。不过还是找不到了,于是乎,就借了“海佩”同志的借鉴一下

速算游戏

(fun.pas/c/cpp)

【问题描述】

jyx和cyy打赌,比谁24点算得快,算得慢的那个人请客。24点的规则是这样的:给定4个1..9的整数,用括号改变运算顺序,通过加、减、乘、除通的一系列运算,得到整数24,注意所有中间结果必须是整数(例如(2*2)/4是允许的,而2*(2/4)是不允许的)。为了赢得这个比赛,请写一个程序帮助我作弊,快速地计算出24点。

【输入】

输入文件fun.in包含一行4个整数,为给定的4个数字。输入数据保证有解。

【输出】

输出文件fun.out一行,以字符串的形式输出结果,注意将每一步的运算的括号补齐(例如(3+5)+6和3*(5+6))如果有多种解答,输出字典顺序最小的一个。

【样例输入输出】

fun.in 
2 3 5 7

fun.out

(((3*5)+2)+7)


type list=array[1..4] of integer;
   last=array[1..4] of string;
var num:list;
   numnow:list;
   strnow:last;
   i,j,k,l,m:integer;
   min:string;
procedure init;
begin
   read(num[1],num[2],num[3],num[4]);
end;
procedure doing(num:list;str:last;k:integer);
var i,j,o:integer;
   numm:list;
   strr:last;
   ss:string;
begin
   fillchar(numm,sizeof(numm),0);
   if (k=1) then
   begin
      if (num[1]=24) and (str[1]<min) then
	 min:=str[1];
      exit;
   end;
   for i:=1 to 4 do
      case i of
	1:begin
	     for j:=1 to k-1 do
	     begin
		for o:=1 to j-1 do
		begin
		   numm[o]:=num[o];
		   strr[o]:=str[o];
		end;
		numm[j]:=num[j]+num[j+1];
		strr[j]:='('+str[j]+'+'+str[j+1]+')';
		for o:=j+1 to k-1 do
		begin
		   numm[o]:=num[o+1];
		   strr[o]:=str[o+1];
		end;
		doing(numm,strr,k-1);
	     end;
	  end;
	2:begin
	     for j:=1 to k-1 do
	     begin
		for o:=1 to j-1 do
		begin
		   numm[o]:=num[o];
		   strr[o]:=str[o];
		end;
		numm[j]:=num[j]-num[j+1];
		strr[j]:='('+str[j]+'-'+str[j+1]+')';
		for o:=j+1 to k-1 do
		begin
		   numm[o]:=num[o+1];
		   strr[o]:=str[o+1];
		end;
		doing(numm,strr,k-1);
	     end;
	  end;
	3:begin
	     for j:=1 to k-1 do
	     begin
		for o:=1 to j-1 do
		begin
		   numm[o]:=num[o];
		   strr[o]:=str[o];
		end;
		numm[j]:=num[j]*num[j+1];
		strr[j]:='('+str[j]+'*'+str[j+1]+')';
		for o:=j+1 to k-1 do
		begin
		   numm[o]:=num[o+1];
		   strr[o]:=str[o+1];
		end;
		doing(numm,strr,k-1);
	     end;
	  end;
	4:begin
	     for j:=1 to k-1 do
		if (num[j+1]<>0) then
                  if (num[j] mod num[j+1]=0) then
		begin
		   for o:=1 to j-1 do
		   begin
		      numm[o]:=num[o];
		      strr[o]:=str[o];
		   end;
		   numm[j]:=num[j] div num[j+1];
		   strr[j]:='('+str[j]+'/'+str[j+1]+')';
		   for o:=j+1 to k-1 do
		   begin
		      numm[o]:=num[o+1];
		      strr[o]:=str[o+1];
		   end;
		   doing(numm,strr,k-1);
		end;
	  end;
      end;
end;
begin
   assign(input,'fun.in'); reset(input);
   assign(output,'fun.out'); rewrite(output);
   init;
   min:=#255#255#255#255#255#255#255#255#255#255#255#255;
   for i:=1 to 4 do
   begin
      numnow[1]:=num[i];
      strnow[1]:=chr(num[i]+48);
      for j:=1 to 4 do
	 if i<>j then
	 begin
	    numnow[2]:=num[j];
	    strnow[2]:=chr(num[j]+48);
	    for k:=1 to 4 do
	       if (k<>i) and (k<>j) then
	       begin
		  numnow[3]:=num[k];
		  strnow[3]:=chr(num[k]+48);
		  for l:=1 to 4 do
		     if (l<>i) and (l<>j) and (l<>k) then
		     begin
			numnow[4]:=num[l];
			strnow[4]:=chr(num[l]+48);
			doing(numnow,strnow,4);
		     end;
	       end;
	 end;
   end;
   writeln(min);
   close(input); close(output);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值