发信人: wfaye (打倒北约), 信区: GreatTurn
标 题: 计算24的程序
发信站: BBS 水木清华站 (Wed Feb 7 10:48:30 2001)
看大家一直在孜孜以求的计算24, 不如贴个程序出来,
可以在1秒种之内解决任何计算24的问题. 当然想算25, 26...
也是可以的. 希望以此作为24问题的终结.
#include "stdafx.h"
//
//原理, 将4个数字和3个运算符按"波兰表达式"组成一个序列,
// 计算该序列的值是否为所求目标. 可以对这个序列的组成
// 进行遍历, 以确定是否有解.
//根据我的计算如果只限于用1-10之间的数字计算24, 总共有
// 715个不同的题目, 其中566个有解. 如果是1-13, 则有
// 1820个不同的题目, 其中1362个有解
//
int total = 0; //解的个数
int sp; //当前表达式栈指针
int s; //表达式栈
void Evaluate(int& fz, int& fm)
//计算表达式的值, fz, fm为计算结果的分子, 分母
{
int op, l, m, opn;
op = s; //取栈顶元素
for (l = 0; l 0) //是数字
{
opn = m;
opn = 1;
}
else //是运算符
Evaluate(opn, opn);
}
//根据运算符进行计算
//opn/opn 是第一个操作数,
//opn/opn 是第二个操作数,
switch (op)
{
case -4: //乘法
fz = opn * opn;
fm = opn * opn;
break;
case -3: //加法
fz = opn * opn + opn * opn;
fm = opn * opn;
break;
case -2: //减法
fz = opn * opn - opn * opn;
fm = opn * opn;
break;
case -1: //除法
fz = opn * opn;
fm = opn * opn;
break;
}
}
void Display(CString& m)
//将表达式转换为字符串
{
int i;
CString n;
m = "";
for (i = 0; i < 7; i++)
{
switch (s)
{
case -4: m += " *"; break;
case -3: m += " +"; break;
case -2: m += " -"; break;
case -1: m += " /"; break;
default: n.Format("%3d", s); m += n; break;
}
}
}
void Compute(int target, int a, int b, int c, int d, CStringArray& ma)
// target - 计算结果(一般为24)
// a, b, c, d - 参加计算的4个数
// ma - 解的字符串表达形式
{
int l1, l2, l3, op1, op2, op3;
int l, fz, fm, num;
CString m;
//记录表达式中间四个元素的排列方式
// 其中loc, loc表示第二, 第三两个运算符的位置
// loc, loc表示第一, 第二两个操作数的位置
int loc = {{1, 2, 3, 4}, {1, 3, 2, 4}, {1, 4, 2, 3},
{2, 3, 1, 4}, {2, 4, 1, 3}};
//num中记录a, b, c, d的一个排列
for (l1 = 0; l1 < 4; l1++)
{
num = a;
for (l2 = 0; l2 < 4; l2++)
{
if (l2 == l1) continue;
num = b;
for (l3 = 0; l3 < 4; l3++)
{
if (l3 == l1 || l3 == l2) continue;
num = c;
num = d;
//表达式最后两个必须是数字
s = num;
s = num;
for (l = 0; l < 5; l++)
{
s] = num;
s] = num;
for (op1 = -4; op1 < 0; op1++)
{
//表达式第一个必须运算符
s = op1;
for (op2 = -4; op2 < 0; op2++)
{
s] = op2;
for (op3 = -4; op3 < 0; op3++)
{
s] = op3;
sp = 0;
Evaluate(fz, fm);
//分母不为0, 可以整除, 商为24表示计算成功
if (fm != 0 && fz % fm == 0 && fz / fm == target)
{
Display(m);
ma.Add(m);
total++;
//这里加return就是只求一个解,
//否则是求出全部解(没有考虑剔除重复解)
return;
}
}
}
}
}
}
}
}
}
--
※ 来源:·BBS 水木清华站 smth.org·
(本文采用S-Term文章拷贝脚本拷贝)
==================================================
标 题: 计算24的程序
发信站: BBS 水木清华站 (Wed Feb 7 10:48:30 2001)
看大家一直在孜孜以求的计算24, 不如贴个程序出来,
可以在1秒种之内解决任何计算24的问题. 当然想算25, 26...
也是可以的. 希望以此作为24问题的终结.
#include "stdafx.h"
//
//原理, 将4个数字和3个运算符按"波兰表达式"组成一个序列,
// 计算该序列的值是否为所求目标. 可以对这个序列的组成
// 进行遍历, 以确定是否有解.
//根据我的计算如果只限于用1-10之间的数字计算24, 总共有
// 715个不同的题目, 其中566个有解. 如果是1-13, 则有
// 1820个不同的题目, 其中1362个有解
//
int total = 0; //解的个数
int sp; //当前表达式栈指针
int s; //表达式栈
void Evaluate(int& fz, int& fm)
//计算表达式的值, fz, fm为计算结果的分子, 分母
{
int op, l, m, opn;
op = s; //取栈顶元素
for (l = 0; l 0) //是数字
{
opn = m;
opn = 1;
}
else //是运算符
Evaluate(opn, opn);
}
//根据运算符进行计算
//opn/opn 是第一个操作数,
//opn/opn 是第二个操作数,
switch (op)
{
case -4: //乘法
fz = opn * opn;
fm = opn * opn;
break;
case -3: //加法
fz = opn * opn + opn * opn;
fm = opn * opn;
break;
case -2: //减法
fz = opn * opn - opn * opn;
fm = opn * opn;
break;
case -1: //除法
fz = opn * opn;
fm = opn * opn;
break;
}
}
void Display(CString& m)
//将表达式转换为字符串
{
int i;
CString n;
m = "";
for (i = 0; i < 7; i++)
{
switch (s)
{
case -4: m += " *"; break;
case -3: m += " +"; break;
case -2: m += " -"; break;
case -1: m += " /"; break;
default: n.Format("%3d", s); m += n; break;
}
}
}
void Compute(int target, int a, int b, int c, int d, CStringArray& ma)
// target - 计算结果(一般为24)
// a, b, c, d - 参加计算的4个数
// ma - 解的字符串表达形式
{
int l1, l2, l3, op1, op2, op3;
int l, fz, fm, num;
CString m;
//记录表达式中间四个元素的排列方式
// 其中loc, loc表示第二, 第三两个运算符的位置
// loc, loc表示第一, 第二两个操作数的位置
int loc = {{1, 2, 3, 4}, {1, 3, 2, 4}, {1, 4, 2, 3},
{2, 3, 1, 4}, {2, 4, 1, 3}};
//num中记录a, b, c, d的一个排列
for (l1 = 0; l1 < 4; l1++)
{
num = a;
for (l2 = 0; l2 < 4; l2++)
{
if (l2 == l1) continue;
num = b;
for (l3 = 0; l3 < 4; l3++)
{
if (l3 == l1 || l3 == l2) continue;
num = c;
num = d;
//表达式最后两个必须是数字
s = num;
s = num;
for (l = 0; l < 5; l++)
{
s] = num;
s] = num;
for (op1 = -4; op1 < 0; op1++)
{
//表达式第一个必须运算符
s = op1;
for (op2 = -4; op2 < 0; op2++)
{
s] = op2;
for (op3 = -4; op3 < 0; op3++)
{
s] = op3;
sp = 0;
Evaluate(fz, fm);
//分母不为0, 可以整除, 商为24表示计算成功
if (fm != 0 && fz % fm == 0 && fz / fm == target)
{
Display(m);
ma.Add(m);
total++;
//这里加return就是只求一个解,
//否则是求出全部解(没有考虑剔除重复解)
return;
}
}
}
}
}
}
}
}
}
--
※ 来源:·BBS 水木清华站 smth.org·
(本文采用S-Term文章拷贝脚本拷贝)
==================================================
ko20010214
=================================
大功告成,打个Kiss!
ko20010214@MSN.com
神州优雅Q300C
Intel CeleronM 370处理器 | 256MbDDR内存
40G硬盘 | USB2.0 | IEEE 1394
13.3 ' WXGA 宽屏(16:10) | COMBO光驱
10/100M网卡 | 四合一读卡器
=================================
大功告成,打个Kiss!
ko20010214@MSN.com
神州优雅Q300C
Intel CeleronM 370处理器 | 256MbDDR内存
40G硬盘 | USB2.0 | IEEE 1394
13.3 ' WXGA 宽屏(16:10) | COMBO光驱
10/100M网卡 | 四合一读卡器

*pp2)='+'; break;
;