前几天看电视“老公看你的”,里面曾出现一节目,主持人3分钟内完成11题目的24点计算。其实,这是个老游戏,一直想解决求解的方法,到网上找一下,程序挺多,看的头晕,随自己编程解决。================================解题思路:1、只有两个数据,进行加减乘除计算,结果若是24,则保存计算过程,返回!2、若多于2个数据,比如n个数据。就从n个数据中任意抽出2个数据进行加减乘除计算,结果和原来剩余的数据组成了新的n-1个数据3、循环执行1、24、显示结果Program.cs:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace _24
{
    class Program
    {
        static HashSet<string> rs = new HashSet<string>();
        static void Main(string[] args)
        {
            for (int i = 1; i <= 13; ++i)
            {
                for (int j = i; j <= 13; ++j)
                {
                    for (int k = j; k < 13; ++k)
                    {
                        for (int m = k; m <= 13; ++m)
                        {
                            C24(new Number[]{ new Number(i), new Number(j), new Number(k), new Number(m) });
                            string[]r=rs.ToArray<string>();
                            for (int n = 0; n < r.Length; ++n)
                            {
                                Console.Write("\n{0,3:d}{1,3:d}{2,3:d}{3,3:d} :", i, j, k, m);
                                Console.Write(string.Format("  {0}", r[n])); break;  //加上break语句,可显示多种解法中的一种
                            }
                            rs.Clear();
                        }
                    }
                }
            }
            Console.ReadKey();
        }        static void C24(Number[] a)
        {
            Number n;
            if (a.Length == 2)
            {
                n = a[0] + a[1]; if (n == 24) { rs.Add(n.ToString()); return; }
                n = a[0] - a[1]; if (n == 24) { rs.Add(n.ToString()); return; }
                n = a[1] - a[0]; if (n == 24) { rs.Add(n.ToString()); return; }
                n = a[0] * a[1]; if (n == 24) { rs.Add(n.ToString()); return; }
                n = a[0] / a[1]; if (n == 24) { rs.Add(n.ToString()); return; }
                n = a[1] / a[0]; if (n == 24) { rs.Add(n.ToString()); return; }
            }
            else
            {
                HashSet<double> hs = new HashSet<double>();
                for (int i = 0; i < a.Length - 1; ++i)
                {
                    for (int j = i + 1; j < a.Length; ++j)
                    {
                        if (!(!hs.Add(a[i] * 1000 + a[j]) || !hs.Add(a[j] * 1000 + a[i])))
                        {
                            List<Number> li = new List<Number>();
                            for (int k = 0; k < a.Length; ++k)
                            {
                                if (!(k == i || k == j)) li.Add(a[k]);
                            }
                            int last = li.Count;
                            li.Add(a[i] + a[j]); C24(li.ToArray()); li.RemoveAt(last);
                            li.Add(a[i] - a[j]); C24(li.ToArray()); li.RemoveAt(last);
                            li.Add(a[j] - a[i]); C24(li.ToArray()); li.RemoveAt(last);
                            li.Add(a[i] * a[j]); C24(li.ToArray()); li.RemoveAt(last);
                            li.Add(a[i] / a[j]); C24(li.ToArray()); li.RemoveAt(last);
                            li.Add(a[j] / a[i]); C24(li.ToArray()); li.RemoveAt(last);
                        }
                    }
                }
            }
        }
    }
}

解决方案 »

  1.   

    Number.cs:using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;namespace _24
    {
        class Number
        {
            private int op;                     // 0:独立的一个数  1:乘法  2:除法  3:加法  4:减法
            private double d;                   // 存放计算的结果,如:0.25
            private string exp;                 // 存放计算的过程,如:1/5        public Number(double n1)
            {
                d = n1; exp = n1.ToString(); op = 0;
            }        public Number(double d,string exp,int op )
            {
                this.d = d; this.exp = exp; this.op = op;
            }        public static Number operator +(Number n1, Number n2)
            {
                return new Number(n1.d + n2.d, n1.exp + "+" + n2.exp, 3);
            }        public static Number operator -(Number n1, Number n2)
            {
                return new Number(n1.d - n2.d, n1.exp + "-" + n2.exp, 4);
            }        public static Number operator *(Number n1, Number n2)
            {
                string exp = (n1.op >= 3 ? "(" + n1.exp + ")" : n1.exp) + "*" + (n2.op >= 3 ? "(" + n2.exp + ")" : n2.exp);
                return new Number(n1.d * n2.d, exp, 1);
            }        public static Number operator /(Number n1, Number n2)
            {
                string exp = (n1.op >= 3 ? "(" + n1.exp + ")" : n1.exp) + "/" + cc(n2);
                return new Number(n1.d / n2.d, exp, 2);
            }        public static implicit operator double(Number n)    
            {
                return n.d;
            }        public override string ToString()       // ToString()
            {
                return this.exp;
            }        private static string jj(Number n)      // 改变加减符号
            {
                if (n.op <= 2) return n.exp;
                return Regex.Replace(n.exp, "[+-]", delegate(Match m)
                {
                    string replaces = m.Value;
                    if (replaces == "+") return "-";
                    return "+";
                });
            }        private static string cc(Number n)      // 改变乘除符号
            {
                if (n.op == 0) return n.exp;
                if (n.op >= 3) return "(" + n.exp + ")";
                return Regex.Replace(n.exp, "[*/]", (Match m) =>
                {
                    string replaces = m.Value;
                    if (replaces == "*") return "/";
                    return "*";
                });
            }
        }
    }
      

  2.   

    迭代的思想,很不错啊,可以适用于n个数不过我觉得如果只做4个数的话应该有更好的做法。感觉这个表达式可以用一个树来表示,而且只有一下两种树,不管哪种数,总共有3个运算符(OP)和4个数字(N)
    问题就变为把四个数字分配到四个N的位置,并且选定3个运算符
    总共有
    4*3*2*1*4*4*4*2=3072种可能
    这么少的可能直接让计算机遍历就可以了吧            //         (OP)
                //        /    \
                //    (OP)      (OP)
                //    /  \      /  \
                //   N    N    N    N            //         (OP)
                //        /    \
                //    (OP)      N
                //    /   \     
                //   (OP)  N  
                //   / \
                //  N   N
      

  3.   

    不好意思,做“撤销”操作时不小心多操作啦,造成一些测试数据所“显示的运算过程”错误,下面的函数写错了,这里是正确的版本!public static Number operator -(Number n1, Number n2)
    {
        return new Number(n1.d - n2.d, n1.exp + "-" + jj(n2), 4);
    }