1) 随机给出 4 个数字(1~9),要求只用加减乘除判断是否能够算出 24,如果能够算出,需要给出计算过程(需要加括号的地方必须加上括号),如果没有解,则显示“无解!”;
2) 也可以实现用户输入计算表达式,由程序来验证的功能,如果正确,则显示“你真棒!”的结果,否则,显示“输入错误,请重试!”;
3) 程序具有检错功能;
4) 编写菜单系统;
完整代码,还有隐藏模式……输入m列出全部可能的题和答案
VS2019编译通过。
#define _CRT_SECURE_NO_WARNINGS
#include <time.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int const NUMBERCOUNT = 4;
float const RESULT = 24;
bool isHit = false;
char* ExpressPool;
int PoolIdx;
int MAX_RESULT = 5000;
bool m_mode;
enum OPT {
PLU,//加
MIN,//减
MINBY,//被减
MUL,//乘
DIV,//除
DIVBY//被除
};
float cal(int ncount, float* nums, char* exps)
{
float a, b;
if (ncount == 2)
{
a = nums[0];
b = nums[1];
OPT opt;
float result = 0.0f;
for (opt = PLU; opt <= DIVBY; opt = (OPT)(opt + 1))
{
switch (opt)
{
case PLU:
result = a + b;
if (result == RESULT)
{
sprintf(ExpressPool + PoolIdx * 32, "%s+%s", exps, exps + 32);
PoolIdx++;
sprintf(ExpressPool + PoolIdx * 32, "%s+%s", exps + 32, exps);
PoolIdx++;
isHit = true;
}
break;
case MIN:
result = a - b;
if (result == RESULT)
{
sprintf(ExpressPool + PoolIdx * 32, "%s-%s", exps, exps + 32);
PoolIdx++;
isHit = true;
}
break;
case MINBY:
result = b - a;
if (result == RESULT)
{
sprintf(ExpressPool + PoolIdx * 32, "%s-%s", exps + 32, exps);
PoolIdx++;
isHit = true;
}
break;
case MUL:
result = a * b;
if (result == RESULT)
{
sprintf(ExpressPool + PoolIdx * 32, "%s*%s", exps, exps + 32);
PoolIdx++;
sprintf(ExpressPool + PoolIdx * 32, "%s*%s", exps + 32, exps);
PoolIdx++;
isHit = true;
}
break;
case DIV:
if (b == 0)continue;
result = a / b;
if (result == RESULT)
{
sprintf(ExpressPool + PoolIdx * 32, "%s/%s", exps, exps + 32);
PoolIdx++;
isHit = true;
}
break;
case DIVBY:
if (a)continue;
result = b / a;
if (result == RESULT)
{
sprintf(ExpressPool + PoolIdx * 32, "%s/%s", exps + 32, exps);
PoolIdx++;
isHit = true;
}
break;
}
}
}
else
{
for (int i = 0; i < ncount; i++)
{
for (int j = 0; j < ncount; j++)
{
if (i != j)
{
int newcount = ncount - 1;
float* num = new float[newcount];
char* newexps = (char*)malloc(32 * newcount);
memset(newexps, 0, 32 * newcount);
int idx = 1;
for (int m = 0; m < ncount; m++)
{
if (m != i && m != j)
{
num[idx] = nums[m];
strcpy(newexps + idx * 32, exps + m * 32);
idx++;
}
}
OPT opt;
for (opt = PLU; opt <= DIVBY; opt = (OPT)(opt + 1))
{
switch (opt)
{
case PLU:
num[0] = nums[i] + nums[j];
sprintf(newexps, "(%s+%s)", exps + i * 32, exps + j * 32);
break;
case MIN:
num[0] = nums[i] - nums[j];
sprintf(newexps, "(%s-%s)", exps + i * 32, exps + j * 32);
break;
case MINBY:
num[0] = nums[j] - nums[i];
sprintf(newexps, "(%s-%s)", exps + j * 32, exps + i * 32);
break;
case MUL:
num[0] = nums[i] * nums[j];
sprintf(newexps, "(%s*%s)", exps + i * 32, exps + j * 32);
break;
case DIV:
if (nums[j] == 0)continue;
num[0] = nums[i] / nums[j];
sprintf(newexps, "(%s/%s)", exps + i * 32, exps + j * 32);
break;
case DIVBY:
if (nums[i] == 0)continue;
num[0] = nums[j] / nums[i];
sprintf(newexps, "(%s/%s)", exps + j * 32, exps + i * 32);
break;
}
cal(newcount, num, newexps);
}
}
}
}
}
return 0;
}
int autoanswer(float* num)
{
int ret = 0;
ExpressPool = (char*)malloc(MAX_RESULT * 32);
memset(ExpressPool, 0, MAX_RESULT * 32);
PoolIdx = 0;
char* exps = (char*)malloc(32 * NUMBERCOUNT);
memset(exps, 0, 32 * NUMBERCOUNT);
for (int i = 0; i < NUMBERCOUNT; i++)
{
if ((exps + i * 32) != 0)
sprintf(exps + i * 32, "%d", (int)num[i]);
}
isHit = false;
cal(NUMBERCOUNT, num, exps);
if (!isHit)
{
if (!m_mode)
{
printf("此题无解!\n");
}
}
else
{
for (int i = 0; i < MAX_RESULT; i++)
{
char firstchar = *(ExpressPool + i * 32);
if (firstchar != '\0')
{
if (!m_mode)
{
printf("%s = %d\n", ExpressPool + i * 32, (int)RESULT);
}
ret++;
for (int j = i + 1; j < MAX_RESULT; j++)
{
char newfirstchar = *(ExpressPool + j * 32);
if (newfirstchar != '\0')
{
char* str1 = (char*)(ExpressPool + i * 32);
char* str2 = (char*)(ExpressPool + j * 32);
int cmpresult = strcmp(ExpressPool + i * 32, ExpressPool + j * 32);
if (cmpresult == 0)
{
memset(ExpressPool + j * 32, '\0', 32);
}
}
}
}
}
}
return ret;
}
int main() {
float num[NUMBERCOUNT];
srand((unsigned int)(time(NULL)));
char c;
printf("\n\n");
printf("**********************************************************\n");
printf("* *\n");
printf("* 计算24游戏 *\n");
printf("* *\n");
printf("* 随机产生4个(0-9)的数字,判断是否能通过+-*/得到24 *\n");
printf("* *\n");
printf("* 茂大叔提供 *\n");
printf("* *\n");
printf("**********************************************************\n\n");
printf("[enter]=随机计算;a=用户答题;q=退出\n");
printf("请输入命令:");
c = getchar();
while (c != 'q') {
m_mode = false;
printf("备选数字为:");
for (int i = 0; i < NUMBERCOUNT; i++)
{
num[i] = (float)(rand() % 9 + 1);
printf(" %d", (int)num[i]);
}
if (c == 'a')
{
char ans[32] = "null";
printf("\n请输入你的答案(除最后一步外,每一个步骤均用括号包围,输入0代表无解):\n");
scanf("%s", ans);
getchar();
printf("正确答案可以为:\n");
int ret = autoanswer(num);
printf("共计 %d 条:\n", ret);
bool correct = false;
if (!isHit && ans[0] == '0')
{
correct = true;
}
else
{
for (int i = 0; i < 100; i++)
{
char firstchar = *(ExpressPool + i * 32);
if (firstchar != '\0')
{
char* str1 = (char*)(ExpressPool + i * 32);
int cmpresult = strcmp(ExpressPool + i * 32, ans);
if (cmpresult == 0)
{
correct = true;
}
}
}
}
free(ExpressPool);
if (!correct)
{
printf("\n很遗憾,答错了~!\n");
}
else
{
printf("\n恭喜你,答对了~!\n");
}
}
if (c == '\n')
{
printf("\n不尝试自己做一做么?回车看答案!\n");
getchar();
printf("答案可以为:\n");
int ret = autoanswer(num);
printf("共计 %d 条:\n", ret);
free(ExpressPool);
}
if (c == 'm')
{
m_mode = true;
for (int n1 = 1; n1 < 10; n1++)
for (int n2 = 1; n2 < 10; n2++)
for (int n3 = 1; n3 < 10; n3++)
for (int n4 = 1; n4 < 10; n4++)
{
num[0] = (float)n1;
num[1] = (float)n2;
num[2] = (float)n3;
num[3] = (float)n4;
int ret = autoanswer(num);
printf("======================\n%d %d %d %d\n", n1, n2, n3, n4);
printf("%s = %d\n", ExpressPool, (int)RESULT);
free(ExpressPool);
}
}
printf("\n[enter]=随机计算;a=用户答题;q=退出\n");
printf("请输入命令:");
c = getchar();
}
printf("再见~!");
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int mark_int[4] = { 1,2,3,4 };
string mark_char = "+-*/";
double cal(double a, int m, double b)
{
switch (m)
{
case 1: return a + b;
case 2: return a - b;
case 3: return a * b;
case 4: return a / b;
}
}
bool cal1(double a, double b, double c, double d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(a, m1, b);
r2 = cal(r1, m2, c);
r3 = cal(r2, m3, d);
if (r3 == 24)
{
cout << "(((" << a << mark_char[m1 - 1] << b << ")" << mark_char[m2 - 1] << c << ")" << mark_char[m3 - 1] << d << ")" << endl;
return 1;
}
return 0;
}
bool cal2(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(b, m1, c);
r2 = cal(a, m2, r1);
r3 = cal(r2, m3, d);
if (r3 == 24)
{
cout << "((" << a << mark_char[m1 - 1] << "(" << b << mark_char[m2 - 1] << c << "))" << mark_char[m3 - 1] << d << ")" << endl;
return 1;
}
return 0;
}
bool cal3(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(b, m1, c);
r2 = cal(r1, m2, d);
r3 = cal(a, m3, r2);
if (r3 == 24)
{
cout << "(" << a << mark_char[m1 - 1] << "((" << b << mark_char[m2 - 1] << c << ")" << mark_char[m3 - 1] << d << "))" << endl;
return 1;
}
return 0;
}
bool cal4(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(c, m1, d);
r2 = cal(b, m2, r1);
r3 = cal(a, m3, r2);
if (r3 == 24)
{
cout << "(" << a << mark_char[m1 - 1] << "(" << b << mark_char[m2 - 1] << "(" << c << mark_char[m3 - 1] << d << ")))" << endl;
return 1;
}
return 0;
}
bool cal5(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(a, m1, b);
r2 = cal(c, m3, d);
r3 = cal(r1, m2, r2);
if (r3 == 24)
{
cout << "((" << a << mark_char[m1 - 1] << b << ")" << mark_char[m2 - 1] << "(" << c << mark_char[m3 - 1] << d << "))" << endl;
return 1;
}
return 0;
}
bool all_cal(int a, int b, int c, int d)
{
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++)
for (int k = 1; k <= 4; k++)
{
if (cal1(a, b, c, d, i, j, k) == true || cal2(a, b, c, d, i, j, k) == true || cal3(a, b, c, d, i, j, k) == true || cal4(a, b, c, d, i, j, k) == true || cal5(a, b, c, d, i, j, k) == true)
return 1;
}
return 0;
}
bool judge(int a, int b, int c, int d)
{
int all[24][4] = {
{a,b,c,d},{a,b,d,c},{a,c,b,d},{a,c,d,b},{a,d,b,c},{a,d,c,b},
{b,a,c,d},{b,a,d,c},{b,c,a,d},{b,c,d,a},{b,d,a,c},{b,d,c,a},
{c,a,b,d},{c,a,d,b},{c,b,a,d},{c,b,d,a},{c,d,a,b},{c,d,b,a},
{d,a,b,d},{d,a,d,b},{d,b,a,c},{d,b,c,a},{d,c,a,b},{d,c,b,a},
};
for (int i = 0; i < 24; i++)
{
if (all_cal(all[i][0], all[i][1], all[i][2], all[i][3]))
return 1;
}
return 0;
}
int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
if (!judge(a, b, c, d))
cout << "凑不成24点" << endl;
}