`
qdzheng
  • 浏览: 67745 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

趣味编程:24点算法实现

    博客分类:
  • Java
阅读更多
24点游戏规则:任取1-9之间的4个数字,用+-*/()连结成算式,使得式子的计算结果为24。估计很多人都玩过用扑克牌玩的那种,印象中10也算在内的,两人各出2张牌,谁先算出来谁赢,赢家收回已经算过的4张牌。最后看谁手里的牌多。
这个程序实现使用穷举的方法,将所有可能的排列穷举出来,最后将每个排列中计算出结果。计算结果时,将前两个作为一组、后两个数作为一组,分别计算出各组的结果,再对获得的两个组结果进行计算。由于是排列,分前后两组进行计算就可满足所有可能的计算。

改进后的代码见回复中。

package fun.twentyfour;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class TwentyFour {
	public static void main(String[] args){
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		String line;
		try{
			while((line=br.readLine())!=null){
				try{
					if ("exit".equals(line)) break;
					
					String[] s=line.split("\\s");
					int[] v=new int[4];
					for(int idx=0;idx<4;idx++) {
						v[idx]=Integer.parseInt(s[idx]);
						if (v[idx]<=0||v[idx]>=10) throw new Exception("Input error.");
					}
					evaluate(v);
					
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	public static void evaluate(int[] v){
		int idx=0;
		for(int a=0;a<4;a++)
			for(int b=0;b<4;b++)
				for (int c=0;c<4;c++)
					for (int d=0;d<4;d++){
					if (a!=b && a!=c && a!=d && b!=c && b!=d && c!=d){
						idx++;
						check(v,new int[]{a,b,c,d});
					}
				}
	}
	static char[] op={'+','-','*','/'};
	public static void check(int[] v,int[] idx){
		
		for(int o=0;o<4;o++){
			for(int p=0;p<4;p++){
				for(int t=0;t<4;t++){
					if (op(op[p],op(op[o],v[idx[0]],v[idx[1]]),op(op[t],v[idx[2]],v[idx[3]]))==24){
						System.out.println(String.format("(%1$d %2$c %3$d) %4$c (%5$d %6$c %7$d)",
								v[idx[0]],op[o],v[idx[1]],op[p],v[idx[2]],op[t],v[idx[3]]));
					}
				}
			}
		}
	}

	public static int op(char op,int v1,int v2){
		switch(op){
		case '+':
			return v1+v2;
		case '-':
			return v1-v2;
		case '*':
			return v1*v2;
		case '/':
			if (v2==0) return -111;
			if (v1%v2!=0) return -111;
			return v1/v2;
		default:
				return 0;
		}
	}
}
分享到:
评论
25 楼 yukaizhao 2009-01-13  
呵呵,我上学的时候用vb写过这个。
24 楼 抛出异常的爱 2009-01-13  
C4取2  * c4取1 *  c3取2  * c4取1  *c2取2 * c4取1

-----------------------------
1.
4个数取2  4种运算取一种
2.
把得数放回原数据中
3.
3个数取2  4种运算取一种
4.
把得数放回原数据中
5.
2个数取2  4种去处取一种
23 楼 kjj 2009-01-12  
大家能不能说一下自己的算法 1-9 个数字组合【可以重复,因为扑克牌可以出现四个一样的数字】共可以得出多少种合法的组合
22 楼 kjj 2009-01-12  
大家能不能说一下自己的算法 1-9 个数字组合【可以重复,因为扑克牌可以出现四个一样的数字】共可以得出多少种合法的组合
21 楼 graying 2009-01-12  
我5年前写过一个算法,24点的,出现的重复很少。

提示:

+,*,是没有逆运算的
-,虽然有逆运算,但是可以不用考虑的
/ 有逆运算,例如 (5-1/5)*5

给每个符号设定优先级,1、2、3,另外我的算法里面还考虑到了 ^, log, √(根号)(还有些奇奇怪怪的符号,不好意思说)

/ 1 没有意义,因为 /1 = *1

有逆运算的符号其实就是做为第二个参数,如果后者符号也可逆运算,就要加括号,例如:1/5/2 和 1/(5/2)是不一样的

基本上现在跑出来的程序结果令人满意,只会出现一些类似:
9 * 8 / 3 = 24 和 9 / (3 / = 24 这样实在不高兴去区分的“同意”公式
20 楼 抛出异常的爱 2009-01-12  
qamer 写道
建立数据字典,优先字典组合,其次才是穷举

如果声明了返回类应该能少几行,还有些代码能少几行....用异常也可以少几行.


public class My24Point {
	static LinkedList<Integer> link = new LinkedList<Integer>();
	static StringBuffer buffer ;
	public static void main(String[] args) {

		Integer[] array = {3,2,5,4};

		myRodem( array);
	}

	private static void myRodem( Integer[] array) {
		Integer tmp = 0 ;

		while(tmp!=24){	
			tmp =0 ;
			link.clear();
			for(Object o :array){
				link.add((Integer) o);
			}
			for(int i =0 ; i<3;i++){
				tmp = My24Point.getSum(link);
				if(tmp==null){
					tmp =0;
					break;
				}
				link.add(tmp);
			}
			System.out.println("\t\t|"+tmp);
			
		}
	}
	
	public static Integer getSum(LinkedList<Integer> link){
		int sum = 0;
		int first = link.remove(new Random().nextInt(link.size()));
		int next = link.remove(new Random().nextInt(link.size()));
		int symbol = new Random().nextInt(4);
		if(symbol == 0){
			sum = first +next;
			System.out.print("sum:"+first+"+"+next +"="+sum);
		}else if(symbol==1){
			sum = first -next;
			System.out.print("sum:"+first+"-"+next +"="+sum);
		}else if(symbol==2){
			sum = first *next;
			System.out.print("sum:"+first+"*"+next +"="+sum);
		}else if(symbol==3&&next!=0 &&first%next==0){
			sum = first / next;
			System.out.print("sum:"+first+"+"+next +"="+sum);
		}else if(symbol==3&&first!=0&& next/first==0){
			sum = next / first;
			System.out.print("sum:"+next+"/"+first +"="+sum);
		}else{
			return null;
		}
		return sum;
	}

}


public class My24Point {
    static LinkedList<Integer> link = new LinkedList<Integer>();
    static StringBuffer buffer ;
    public static void main(String[] args) {
        Integer[] array = {3,2,5,4};
        myRodem( array,24);
    }
    private static void myRodem( Integer[] array,int max) {
        Integer tmp = 0 ;
        while(tmp!=max){    
            tmp =0 ;link.clear();buffer = new StringBuffer();
            for(Object o :array){link.add((Integer) o);    }
            while(link.size()>=2){
                tmp = My24Point.getSum(link);
                                if(tmp==null){    tmp =0;    break;}
                link.add(tmp);buffer.append("|");
            }
            System.out.println(buffer.toString()+"\t\t|"+tmp);
        }
    }    
    public static Integer getSum(LinkedList<Integer> link){
        int sum = 0;
        int first = link.remove(new Random().nextInt(link.size()));
        int next = link.remove(new Random().nextInt(link.size()));
        int symbol = new Random().nextInt(4);
        if(symbol == 0){ 
            sum = first +next;buffer.append(first+"+"+next +"="+sum);
        }else if(symbol==1){
            sum = first -next;buffer.append(first+"-"+next +"="+sum);
        }else if(symbol==2){
            sum = first *next;buffer.append(first+"*"+next +"="+sum);
        }else if(symbol==3&&next!=0 &&first%next==0){
            sum = first / next;buffer.append(first+"+"+next +"="+sum);
        }else if(symbol==3&&first!=0&& next/first==0){
            sum = next / first;buffer.append(next+"/"+first +"="+sum);
        }else{return null;}
        return sum;
    }

}
19 楼 qamer 2009-01-12  
建立数据字典,优先字典组合,其次才是穷举
18 楼 100_percent 2009-01-12  
算法不优化,代码过长
17 楼 libudi 2009-01-12  
用 Lysee 实现一个穷尽的:
public varlist help(varlist list, bool loose)
{
  for [int a in 4 : int b in 4 : int c in 4 : int d in 4] 
    if (loose or ((1 << a) + (1 << b) + (1 << c) + (1<< d) == 14))
      return [list[a], list[b], list[c], list[d]];
}

public strlist evaluate(int a b c d)
{
  strlist result = strlist();
  for [varlist v in yield(help, [[a, b, c, d], 0]) if (v):
       varlist o in yield(help, [['+', '-', '*', '\\'], 1]) if (o):
       string x in ["(%[0]%[4]%[1])%[5](%[2]%[6]%[3])", 
                    "((%[0]%[4]%[1])%[5]%[2])%[6]%[3]",
                    "(%[0]%[4](%[1]%[5]%[2]))%[6]%[3]", 
                    "%[0]%[4]((%[1]%[5]%[2])%[6]%[3])",
                    "%[0]%[4](%[1]%[5](%[2]%[6]%[3]))"]] {
    x = format(x, v + o).trim();
    result.add(x) if (eval("return " + x) == 24); 
  }
  result.unique();
  return result;
}

= evaluate(3, 6, 1, 9);
16 楼 kjj 2009-01-12  
sdh5724 写道
谁能把代码控制在20行之内, 又有一定可读性。
比赛开始, 楼下继续。

看来这位仁兄可以在20行之内写出如此可读的代码,能否那出来,让我等学习学习呢
15 楼 gbb21 2009-01-12  
sdh5724 写道
谁能把代码控制在20行之内, 又有一定可读性。
比赛开始, 楼下继续。

把我python代码里面的记忆处理/或者表达式输出 去掉就20行以内了~
14 楼 sdh5724 2009-01-11  
谁能把代码控制在20行之内, 又有一定可读性。
比赛开始, 楼下继续。
13 楼 lemo 2009-01-11  
学习。。。
12 楼 kjj 2009-01-11  
楼上是否可以给个递归的算法学习学习
11 楼 terencewong 2009-01-11  
这是求解空间问题,和迷宫走法什么没有什么本质区别吧。
可以用递归求解,求的过程可以配合附加条件适当做剪枝。最后把整个解空间树求出来。
10 楼 kjj 2009-01-11  
恰好我前两天也做了一个,没有考虑优先级,只是把所有的组合和运算符组合了一下,拿上来大家研究研究
package org.qinghua.dispatcher.test;
import java.util.Stack;
public class Gift {
	static String[] oprs = { "+", "-", "*", "/" };
	static Stack<Integer> numStack = new Stack<Integer>();
	static Stack<String> oprStack = new Stack<String>();
	public static void main(String[] args) {
		int num = 0;
		for (int i = 1; i < 10; i++) {
			for (int x = 0; x < 4; x++) {
				for (int j = 1; j < 10; j++) {
					for (int y = 0; y < 4; y++) {
						for (int m = 1; m < 10; m++) {
							for (int z = 0; z < 4; z++) {
								for (int n = 1 ; n < 10; n++) {
									numStack.push(i);								numStack.push(j);								numStack.push(m);								numStack.push(n);								oprStack.push(oprs[x]);							oprStack.push(oprs[y]);							oprStack.push(oprs[z]);							if (cal24(numStack, oprStack)) {						System.out.print(new StringBuffer(i+oprs[x]+j+oprs[y]+m+oprs[z]+n).reverse().toString()+" = 24 " +(++num)+"\n");
	}
	}
							}
						}
					}
				}
			}
		}
	}
	static boolean cal24(Stack<Integer> ints, Stack<String> oprs) {
		int r = 0;
		while (!oprs.empty()) {
			String opr = oprs.pop();
			int a = ints.pop();
			int b = ints.pop();
			r = oprtwo(opr, a, b);
			ints.push(r);
			if (r == 0) {
				ints.clear();
				oprs.clear();
				return false;
			}
			
		}

		if ((r = ints.pop()) == 24) {
			ints.clear();
			oprs.clear();
			return true;
		}
		return false;
	}

	static int oprtwo(String opr, int a, int b) {
		if (opr.equals("+"))
			return a + b;
		if (opr.equals("-"))
			return a - b<0?0:a-b;
		if (opr.equals("*"))
			return a * b;
		if (opr.equals("/") && b != 0 && a > b && isIntegerRst(a, b)) {
			return a / b;
		} else
			return 0;
	}
	static boolean isIntegerRst(int ai, int bi) {
		Integer a = ai;
		Integer b = bi;
		Float an = Float.valueOf(a.toString());
		Float bn = Float.valueOf(b.toString());
		//System.out.println(an/bn);
		return (String.valueOf((an / bn)).endsWith(".0"));
	}
}

就是说,1-9 任意给出四个数字,计算24点,可以重复,运算符任意的合法结果是 2870

out Number : 2870
9 楼 qdzheng 2009-01-11  
改进后的24点算法,也还有缺点,未处理重复组合。使用了类似逆波兰表达式的机制(未考虑算符优先级)。
输入 3 6 1 9后输出为:

3 6 1 9

((3*(6-1))+9)
(((3-1)*9)+6)
(6+((3-1)*9))
((6-3)*(9-1))
(((6-1)*3)+9)
(6*(1+(9/3)))
(6+(9*(3-1)))
(6*((9/3)+1))
(((1+9)*3)-6)
((1+(9/3))*6)
(9+(3*(6-1)))
((9*(3-1))+6)
(((9/3)+1)*6)
(9+((6-1)*3))
(((9+1)*3)-6)
((9-1)*(6-3))

package fun.twentyfour;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;

public class TwentyFour {
	public static void main(String[] args){
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		String line;
		try{
			while((line=br.readLine())!=null){
				try{
					if ("exit".equals(line)) break;
					
					String[] s=line.split("\\s");
					int[] v=new int[4];
					for(int idx=0;idx<4;idx++) {
						v[idx]=Integer.parseInt(s[idx]);
						if (v[idx]<=0||v[idx]>=10) throw new Exception("Input error.");
					}
					evaluate(v);
					
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	public static void evaluate(int[] v){
		for(int a=0;a<4;a++)
			for(int b=0;b<4;b++){
				if (a==b) continue;
				for (int c=0;c<4;c++){
					if (a==c||b==c) continue;
					for (int d=0;d<4;d++){
						if (a==d || b==d || c==d ) continue; 
						check(v,new int[]{a,b,c,d});
					}
				}
			}
		evaluate(new int[]{v[0],v[1],v[2],v[3]},new char[]{'+','+','+'});
		evaluate(new int[]{v[0],v[1],v[2],v[3]},new char[]{'*','*','*'});
	}
	static char[] op={'+','-','*','/'};
	public static void check(int[] v,int[] idx){
		
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				for(int k=0;k<4;k++){
					if (i==j && j==k) continue;
					evaluate(new int[]{v[idx[0]],v[idx[1]],v[idx[2]],v[idx[3]]},new char[]{op[i],op[j],op[k]});
				}
			}
		}
	}

	/**
	 * 计算四个数字排列与操作符的运算结果
	 * @param num  数字排列
	 * @param op  操作符排列
	 */
	public static void evaluate(int[] num,char[] op){
		MyStack stack=new MyStack();
		//要入栈的操作数个数1-4
		int dataNum=0;
		if (op[0]==op[1] && op[0]==op[2]) dataNum=num.length - 1;
		for(;dataNum<num.length;dataNum++){
			//要入栈的操作符个数1-3
			int opNum=0;
			if (dataNum+1==num.length) opNum=op.length-1;
			int maxOpNum=dataNum;
			if (dataNum==0) maxOpNum=1;
			repeat:
			for(;opNum<maxOpNum;opNum++){
				int numCount=0;
				int dataIndex=0;
				int opIndex=0;

				stack.clear();
				
				while(dataIndex<num.length || opIndex<op.length){
					//操作数入栈
					for(int i=0;dataIndex<num.length && i<dataNum+1;i++){
						stack.push(num[dataIndex]);
						dataIndex++;
						numCount++;
					}
					//操作符入栈
					for(int k=0;opIndex<op.length && k<opNum+1;k++){
						if (numCount>1){
							stack.push(op[opIndex]);
							if (stack.isStop()) break repeat;
							opIndex++;
							numCount--;
						}
					}
				}
				if ((Integer)stack.pop()==24){
					System.out.println(stack.toString());
				}
			}
		}
	}

	public static class MyStack extends Stack{
		boolean stop=false;
		Stack stack=new Stack();
		
		public String toString(){
			return getExpression();
		}
		
		public boolean isStop(){
			return stop;
		}
		public String getExpression(){
			Object v=stack.pop();
			if (v instanceof Character){
				String right=getExpression();
				String left=getExpression();
				return "("+left+v+right+")";
			}
			return v.toString();
		}
		public void clear(){
			super.clear();
			stack.clear();
                        stop=false;
		}
		
		public Object push(Object v){
			stack.push(v);
			if (v instanceof Character){
				Integer v1=(Integer)pop();
				Integer v2=(Integer)pop();
				Integer v3=0;
				switch((Character)v){
				case '+': 
					v3=v2+v1;break;
				case '-':
					v3=v2-v1;
					if (v3<0) stop=true;
					break;
				case '*':
					v3=v2*v1;break;
				case '/':
					if (v1!=0 && v2%v1==0){
						v3=v2/v1;
					}else{
						stop=true;
					}
					break;
				}
				return super.push(v3);
			}else{
				return super.push(v);
			}
			
		}
	}
}
8 楼 gbb21 2009-01-10  
好吧,既然C++都来了,偶也就来一个Python 版本,带记忆的(不会重复搜索),带打印结果的
也是穷举,理论上支持任意长度和任意目标值的

operations = [(lambda a, b: a + b, lambda a, b: "( " + str(a) + " + " + str(b) + " )"),
			  (lambda a, b: a - b, lambda a, b: "( " + str(a) + " - " + str(b) + " )"),
			  (lambda a, b: b - a, lambda a, b: "( " + str(b) + " - " + str(a) + " )"),
			  (lambda a, b: a * b, lambda a, b: "( " + str(a) + " * " + str(b) + " )"),
			  (lambda a, b: a // b, lambda a, b: "( " + str(a) + " / " + str(b) + " )"),
			  (lambda a, b: b // a, lambda a, b: "( " + str(b) + " / " + str(a) + " )")]

targetNumber = 24
resultMap = dict()

def search(numSet):
	if len(numSet) <= 1:
		return numSet[0] == targetNumber and " " + str(targetNumber) + " " or None
	numSet.sort();
	if tuple(numSet) in resultMap:
		return resultMap[tuple(numSet)];
	
	for a in range(0, len(numSet) - 1):
		for b in range(a + 1, len(numSet)):
			for op in operations:
				try:
					newList = [n for n in numSet if n != numSet[a] and n != numSet[b]]
					newList.append(op[0](numSet[a], numSet[b]))
					res = search(newList)
					if res:
						res = res.replace(" " + str(op[0](numSet[a], numSet[b])) + " ", op[1](numSet[a], numSet[b]), 1)
						resultMap[tuple(numSet)] = res
						return res
					newList.pop()
				except ZeroDivisionError:
					pass
	resultMap[tuple(numSet)] = None
	return None

if __name__ == "__main__":
	print(search([2, 2, 2, 2]))
	print(search([3, 4, 5, 6, 7]))
7 楼 mt0803 2009-01-09  
拿去研究一下。。。。。。
6 楼 zeeeitch 2009-01-09  
#include "stdafx.h"
#include "iostream"
#include <vector>
#include <algorithm>
#include <map>
#include "point24.h"
using namespace std;

typedef map<pair<int , int > , int > Map;

bool canForm24(int num[]);


int main()
{
	Map map1;

	int n[]={3,3,8,9};
//	cout<<canForm24(n);

	for ( int i=0;i<10;++i)
	for ( int i2=0;i2<10;++i2)
	for ( int i3=0;i3<10;++i3)
	for ( int i4=0;i4<10;++i4)
	{
		n[0]=i;
		n[1]=i2;
		n[2]=i3;
		n[3]=i4;
		sort(n,n+4);
		if(canForm24(n))
		{
			map1[make_pair(n[0],n[1])] = map1[make_pair(n[0],n[1])] + 1 ;
			map1[make_pair(n[0],n[2])] = map1[make_pair(n[0],n[2])] + 1 ;
			map1[make_pair(n[0],n[3])] = map1[make_pair(n[0],n[3])] + 1 ;
			map1[make_pair(n[1],n[2])] = map1[make_pair(n[1],n[2])] + 1 ;
			map1[make_pair(n[1],n[3])] = map1[make_pair(n[1],n[3])] + 1 ;
			map1[make_pair(n[2],n[3])] = map1[make_pair(n[2],n[3])] + 1 ;
		}

	}

	Map::iterator p;
//	copy(map1.begin(),map1.end(),ostream_iterator<pair<int , int > , int  >(cout,"\n"));

	/*
	map<removeMulti::rmAux, int> rmMap;
	map<removeMulti::rmAux, int> rmMap2;
	map<removeMulti::rmAux, int> rmMap3;


	int num[4] ;
	num[0] = 0;
	while (num[0] < 10)
	{
		rmMap.clear();
		rmMap2.clear();
		rmMap3.clear();

		cin >> num[0] >> num[1] >> num[2] >> num[3];

		int arr[] =
		{
			0, 1, 2, 3
		};
		vector<int> arrange(arr, arr + 4);


		Plus p;Minus m; Multi mu; Devide d;Minus2 m2; Devide2 d2;
		OpBase* ops[] =
		{
			&p, & m, & mu, & d, & m2, & d2
		};

		int count = 0;

		ArrangeGenerator<int> ag(arrange);
		while (ag.haveNext())
		{
			arrange = ag.next();
			for (unsigned int j = 0; j < 6 * 6 * 6; ++j)
			{
				OpBase& op1 = *ops[j % 6];
				OpBase& op2 = *ops[(j / 6) % 6];
				OpBase& op3 = *ops[(j / 36) % 6];
				try
				{
					if (op3(op2(op1(num[arrange[0]], num[arrange[1]]),
								num[arrange[2]]),
							num[arrange[3]]) ==
						24)
					{
						removeMulti::rmAux rmaux =
						{
							min(num[arrange[0]], num[arrange[1]]),
							max(num[arrange[0]], num[arrange[1]]),
							op1(num[arrange[0]], num[arrange[1]])
						};

						if (rmMap[rmaux] == 0)
						{
							std::cout << "((" << num[arrange[0]] << op1
								<< num[arrange[1]] << ")" << op2
								<< num[arrange[2]] << ")" << op3
								<< num[arrange[3]] << std::endl;
							count ++;

							rmMap[rmaux] = 1;
						}
					}


					//()+()
					if (op2(op1(num[arrange[0]], num[arrange[1]]),
							op3(num[arrange[2]], num[arrange[3]])) == 24)
					{
						removeMulti::rmAux rmaux =
						{
							min(num[arrange[0]], num[arrange[1]]),
							max(num[arrange[0]], num[arrange[1]]),
							op1(num[arrange[0]], num[arrange[1]])
						};
						removeMulti::rmAux rmaux2 =
						{
							min(num[arrange[2]], num[arrange[3]]),
							max(num[arrange[2]], num[arrange[3]]),
							op3(num[arrange[2]], num[arrange[3]])
						};

						if (rmMap2[rmaux] == 0 && rmMap2[rmaux2] == 0)
						{
							std::cout << "(" << num[arrange[0]] << op1
								<< num[arrange[1]] << ")" << op2 << "("
								<< num[arrange[2]] << op3 << num[arrange[3]]
								<< ")" << std::endl;
							count ++;
							rmMap2[rmaux] = 1;
						}
					}
				}
				catch (int)
				{
				}
			}
		}

		cout << count << endl;
	};
	return 0;*/
}


/**********************************************************************************************************************************
/*********************************************************************************************************************************/

ostream& operator<<(ostream& o, OpBase& ob)
{
	ob.out(o);
	return o;
}

int Plus::operator()(int a, int b)
{
	return a + b;
}
void Plus::out(ostream& o)
{
	o << '+';
}


int Minus::operator()(int a, int b)
{
	return a - b;
}	
void Minus::out(ostream& o)
{
	o << '-';
}

int Minus2::operator()(int a, int b)
{
	return b - a;
}	
void Minus2::out(ostream& o)
{
	o << "-_";
}


int Multi::operator()(int a, int b)
{
	return a * b;
}	
void Multi::out(ostream& o)
{
	o << '*';
}


int Devide::operator()(int a, int b)
{
	if (b == 0)
		throw int(0);
	if (a % b != 0)
		throw int(0);
	return a / b;
}	
void Devide::out(ostream& o)
{
	o << '/';
}

int Devide2::operator()(int a, int b)
{
	if (a == 0)
		throw int(0);
	if (b % a != 0)
		throw int(0);
	return b / a;
}	
void Devide2::out(ostream& o)
{
	o << "/_";
}

bool canForm24(int num[])
{
			//cin >> num[0] >> num[1] >> num[2] >> num[3];

		int arr[] =
		{
			0, 1, 2, 3
		};
		vector<int> arrange(arr, arr + 4);


		Plus p;Minus m; Multi mu; Devide d;Minus2 m2; Devide2 d2;
		OpBase* ops[] =
		{
			&p, & m, & mu, & d, & m2, & d2
		};

		int count = 0;

		ArrangeGenerator<int> ag(arrange);
		while (ag.haveNext())
		{
			arrange = ag.next();
			for (unsigned int j = 0; j < 6 * 6 * 6; ++j)
			{
				OpBase& op1 = *ops[j % 6];
				OpBase& op2 = *ops[(j / 6) % 6];
				OpBase& op3 = *ops[(j / 36) % 6];
				try
				{
					if (op3(op2(op1(num[arrange[0]], num[arrange[1]]),
								num[arrange[2]]),
							num[arrange[3]]) ==
						24)
					{
						return true;
					}


					//()+()
					if (op2(op1(num[arrange[0]], num[arrange[1]]),
							op3(num[arrange[2]], num[arrange[3]])) == 24)
					{
						return true;
					}
				}
				catch (int)
				{
				}
			}
		}

		return false;

}

相关推荐

    小学生C++趣味编程配套教学资源

    以知识点为中心,《小学生C++趣味编程》适D地弱化语法,注重算法。利用流程图厘清思路,激发学习兴趣,培养计算思维。 本资源为官方正版配套教学资源,包含: 1)全书涉及的所有源代码(包含完整代码和不完整代码[即...

    python趣味编程100例(99个)

    "Python趣味编程100例(99个)"这个资源显然是为了帮助初学者通过一系列有趣的实践例子来学习Python编程。 在Python编程中,基础是非常重要的。例如,了解变量的声明和使用,数据类型如整型(int)、浮点型(float)、...

    青少年趣味编程Python系列课程--2019-09-23.pdf

    标题《青少年趣味编程Python系列课程--2019-09-23》以及描述《青少年趣味编程Python系列课程--2019-09-23》揭示了该文件是一份针对青少年的Python编程课程计划,时间为2019年9月23日。文档的标签为“python学习 系列...

    《Scratch趣味编程》.pdf

    《Scratch趣味编程》 《Scratch趣味编程》是一种图形化的编程语言,由美国麻省理工学院研发,可以轻松地创建自己互动故事、动画、游戏、音乐和艺术。 Scratch将程序语言设计成一块块积木,你只要用拖拉的方式,将...

    c++趣味编程配套课件

    C++趣味编程是一门引人入胜的课程,旨在帮助初学者理解编程基础,并通过实践探索编程的乐趣。在这个配套课件中,我们将深入探讨C++语言的各个方面,使其成为掌握编程概念的有效工具。 首先,我们要了解C++的基本...

    趣味矩阵算法实现源代码

    标题中的“趣味矩阵算法实现源代码”意味着我们将探讨一种用编程语言实现的,能够打印或操作特定模式矩阵的方法。这可能包括递归、循环或其他控制结构,以按照预设的规则填充和展示矩阵。 描述中的“算法分析与设计...

    小学生C++趣味编程 C++源代码(2021.11.22).rar

    标题中的“小学生C++趣味编程 C++源代码(2021.11.22).rar”表明这是一个专为小学生设计的C++编程学习资源包,包含了2021年11月22日更新的源代码。这个资源旨在以有趣的方式介绍C++编程基础,帮助孩子们在早期阶段...

    24点游戏的算法及实现

    24点游戏是一种深受人们喜爱的智力挑战游戏,它的...总的来说,24点游戏的算法实现是一个涉及排列组合、数学运算和递归编程的有趣课题。通过学习和实践,我们可以不仅提高编程技巧,还能增强逻辑推理和问题解决能力。

    《小学生C++趣味编程》-C++、Scratch(2023.09.24)C.pdf

    《小学生C++趣味编程》是一本面向初学者,特别是小学生的教材,旨在通过结合C++编程语言和Scratch可视化编程工具,激发孩子们对编程的兴趣。该书内容涵盖基础的编程概念,逐步引导学生掌握编程思维和技能。以下是书...

    python算法趣味题目

    ### Python算法趣味题目详解 #### 题目背景与概述 本文将介绍并解析两道有趣的Python算法题目,旨在帮助读者更好地理解Python语言的特点及其在处理字符串方面的优势。通过具体的示例代码,我们将深入探讨Python...

    python趣味编程100例.7z

    《Python趣味编程100例》是一份专为Python初学者设计的学习资源,它通过100个精心挑选的编程实例,旨在帮助新手快速掌握Python编程的基础知识和实践技巧。这个压缩包包含了丰富的源代码,并且每个示例都有详细的注释...

    Scratch编程入门与算法进阶.pptx

    第二部分是算法进阶,详细介绍了几个经典的算法问题及其对应的Scratch实现。这些问题包括约瑟夫环问题、最长回文子串、0/1背包问题、拓扑排序等。通过这些实例,读者可以深入理解算法的本质和实现方法,提高解决问题...

    Java趣味编程100例 清华大学出版社.zip

    本书取材注重趣味性与实用性,内容涵盖了Java编程的基础知识和常用算法,讲解时给出了实例的详细代码及注释。本书附带1张光盘,收录了本书配套多媒体教学视频及实例源文件,可大大方便读者高效、直观地学习本书内容...

    Scratch编程入门与算法进阶.docx

    Scratch 编程入门与算法进阶 Scratch 是一款为青少年设计的编程语言和平台,由麻省理工学院的媒体实验室(Media Lab)和哈佛大学的实验室(Graduate School of Education)联合开发。Scratch 的起源与发展可以追溯...

    “编”玩边学:Scratch趣味编程进阶妙趣横生的数学和算法.pptx

    "编"玩边学:Scratch趣味编程进阶妙趣横生的数学和算法 《“编”玩边学:Scratch趣味编程进阶妙趣横生的数学和算法》是一本旨在通过Scratch编程语言教授数学和算法知识的书籍。这本书的内容丰富、生动有趣,适合中...

    C/C++趣味编程100例

    《C/C++趣味编程100例》一书精选了100个经典、实用且充满趣味性的程序设计实例,旨在通过实践加深读者对C/C++语言的理解与掌握。本书覆盖了从基本图形绘制到复杂算法实现的广泛内容,不仅适合初学者入门,也能够帮助...

    教学论文:利用Scratch趣味编程与Pascal语言互动教学例谈.docx

    本文主要探讨了如何利用Scratch趣味编程与Pascal语言的互动教学方法,以提高小学生对编程的理解和兴趣。以下是对标题和描述中关键知识点的详细说明: 1. **Scratch趣味编程**:Scratch是一种面向儿童的图形化编程...

    趣味编程百例

    "趣味编程百例"是一个可能包含一系列有趣且富有挑战性的编程练习的集合,旨在帮助学习者提高编程技能,同时享受编程的乐趣。这些编程题目通常涵盖了基础到进阶的各种难度,适合不同程度的程序员进行实践和提升。 在...

    java趣味算法经典趣味算法

    6. **位操作**:Java的位操作可以用于高效地处理二进制数据,如快速幂运算、奇偶性检查等,是实现一些趣味算法的有效手段。 7. **模拟算法**:模拟真实世界的情况,如抛硬币、抽卡等概率问题,可以通过Java程序进行...

    JAVA趣味编程100实例

    在标题“JAVA趣味编程100实例”下,描述中提到“很实用的java趣味编程小程序”,这说明本文件旨在通过有趣的编程实例来帮助学习者加深对Java语言的理解和应用能力。通过解决实际问题来提高编程技能,这些实例很可能...

Global site tag (gtag.js) - Google Analytics