10/01/20 Transform the Expression 解题报告

本文介绍如何将带括号的代数表达式转换为逆波兰表示法(RPN)。通过示例展示了输入输出格式,并提供了一个C语言实现方案,该方案使用栈来处理表达式。

SPOJ Problem Set (classical)

4. Transform the Expression

Problem code: ONP

 

Transform the algebraic expression with brackets into RPN form (Reverse Polish Notation). Two-argument operators: +, -, *, /, ^ (priority from the lowest to the highest), brackets ( ). Operands: only letters: a,b,...,z. Assume that there is only one RPN form (no expressions like a*b*c).

Input

t [the number of expressions <= 100]
expression [length <= 400]
[other expressions]

Text grouped in [ ] does not appear in the input file.

Output

The expressions in RPN form, one per line.

Example

Input:
3
(a+(b*c))
((a+b)*(z+x))
((a+t)*((b+(a+c))^(c+d)))

Output:
abc*+
ab+zx+*
at+bac++cd+^*
 
根据下面代码续写设计交互界面,要有用户的注册和登录界面,要设备自适应布局,有数字卡片的拖拽交互,成功反馈(正确时数字卡片融化粒子动画),动态渐变背景(根据解题时间背景从蓝变为金色),其余可自行创意添加: #include <conio.h>#include <ctype.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#pragma warning(disable:4996)#define MAX_NAME_LEN 20#define MAX_EXPR_LEN 100#define NUM_COUNT 4#define MAX_ROUNDS 3#define MAX_HIGH_SCORES 10// 游戏难度级别(秒)typedef enum { EASY = 60, // 60秒 MEDIUM = 40, // 40秒 HARD = 20 // 20秒} Difficulty;// 高分记录结构typedef struct { char name[MAX_NAME_LEN]; int score;} HighScore;// 游戏状态结构typedef struct { int numbers[NUM_COUNT]; // 四个随机数 char player[MAX_NAME_LEN]; // 玩家名称 int totalScore; // 总分 Difficulty difficulty; // 难度级别 time_t startTime; // 开始时间} GameState;// 全局变量HighScore highScores[MAX_HIGH_SCORES];int numHighScores = 0;/* 函数声明 */void displayMenu();void startGame();void setDifficulty();void showHighScores();int canSolve24(int nums[]);double evaluateExpression(char* expr);int validateExpression(char* expr, int nums[]);int calculateScore(time_t start, time_t end, Difficulty diff);void updateHighScores(char* name, int score);void loadHighScores();void saveHighScores();void clearScreen();/* 主函数 */int main() { srand(time(NULL)); // 初始化随机种子 loadHighScores(); // 加载高分记录 int choice; do { clearScreen(); displayMenu(); printf("请选择操作: "); scanf("%d", &choice); switch (choice) { case 1: startGame(); break; case 2: setDifficulty(); break; case 3: showHighScores(); break; case 4: printf("\n感谢游玩,再见!\n"); break; default: printf("\n无效选择,请重新输入!\n"); getch(); } } while (choice != 4); return 0;}/* 显示主菜单 */void displayMenu() { printf("\n"); printf("***********************************\n"); printf("* 24点游戏 v1.0 *\n"); printf("***********************************\n"); printf("* 1. 开始游戏 *\n"); printf("* 2. 难度设置 *\n"); printf("* 3. 高手榜 *\n"); printf("* 4. 退出游戏 *\n"); printf("***********************************\n");}/* 开始游戏 */void startGame() { GameState game; game.totalScore = 0; game.difficulty = MEDIUM; // 默认难度 clearScreen(); printf("\n请输入您的名称: "); scanf("%s", game.player); for (int round = 0; round < MAX_ROUNDS; round++) { clearScreen(); printf("\n====== 第 %d 轮 ======\n", round + 1); printf("玩家: %s\n", game.player); printf("当前总分: %d\n", game.totalScore); // 生成四个随机数 printf("\n随机数: "); for (int i = 0; i < NUM_COUNT; i++) { game.numbers[i] = rand() % 10 + 1; printf("%d ", game.numbers[i]); } printf("\n"); // 检查是否有解 int solvable = canSolve24(game.numbers); if (!solvable) { printf("\n提示: 这组数字无解,请输入 NO\n"); } game.startTime = time(NULL); // 记录开始时间 time_t endTime; char input[MAX_EXPR_LEN] = { 0 }; int validInput = 0; // 获取玩家输入 while (!validInput) { printf("\n请输入表达式 (或输入NO): "); scanf("%s", input); // 检查是否超时 endTime = time(NULL); if (difftime(endTime, game.startTime) > (double)game.difficulty) { printf("\n时间到!本轮得0分\n"); getch(); break; } // 处理NO输入 if (strcmp(input, "NO") == 0 || strcmp(input, "no") == 0) { if (solvable) { printf("\n错误!本题有解\n"); } else { int timeUsed = (int)difftime(endTime, game.startTime); int score = calculateScore(game.startTime, endTime, game.difficulty); printf("\n正确!用时 %d 秒,得分: %d\n", timeUsed, score); game.totalScore += score; } validInput = 1; } // 处理表达式输入 else { // 验证表达式 if (validateExpression(input, game.numbers)) { double result = evaluateExpression(input); if (fabs(result - 24.0) < 1e-6) { int timeUsed = (int)difftime(endTime, game.startTime); int score = calculateScore(game.startTime, endTime, game.difficulty); printf("\n正确!结果 = %.2f, 用时 %d 秒,得分: %d\n", result, timeUsed, score); game.totalScore += score; validInput = 1; } else { printf("\n计算结果错误 (%.2f ≠ 24),请重试\n", result); } } else { printf("\n表达式无效或未使用全部数字,请重试\n"); } } } printf("\n按任意键继续..."); getch(); } // 游戏结束,更新高分 clearScreen(); printf("\n游戏结束!%s 的总分: %d\n", game.player, game.totalScore); if (game.totalScore > 0) { updateHighScores(game.player, game.totalScore); } printf("\n按任意键返回主菜单..."); getch();}/* 设置难度 */void setDifficulty() { clearScreen(); printf("\n====== 难度设置 ======\n"); printf("1. 简单 (60秒)\n"); printf("2. 中等 (40秒)\n"); printf("3. 困难 (20秒)\n"); printf("4. 返回\n"); int choice; printf("\n请选择难度: "); scanf("%d", &choice); Difficulty newDiff; switch (choice) { case 1: newDiff = EASY; break; case 2: newDiff = MEDIUM; break; case 3: newDiff = HARD; break; default: return; } printf("\n难度已设置为: "); switch (newDiff) { case EASY: printf("简单 (60秒)"); break; case MEDIUM: printf("中等 (40秒)"); break; case HARD: printf("困难 (20秒)"); break; } printf("\n"); // 更新全局难度设置 // (实际游戏中可以保存到全局变量或配置文件中) printf("\n按任意键继续..."); getch();}/* 显示高手榜 */void showHighScores() { clearScreen(); printf("\n====== 高手榜 ======\n"); if (numHighScores == 0) { printf("\n暂无记录\n"); } else { printf("\n排名 玩家 分数\n"); printf("----------------------------\n"); for (int i = 0; i < numHighScores; i++) { printf("%2d. %-15s %5d\n", i + 1, highScores[i].name, highScores[i].score); } } printf("\n按任意键返回..."); getch();}void initGame(){}/* 判断四个数能否计算出24 (DFS算法) */int canSolve24(int nums[]) { double numArr[NUM_COUNT]; for (int i = 0; i < NUM_COUNT; i++) { numArr[i] = (double)nums[i]; } return dfsSolve(numArr, NUM_COUNT);}/* DFS递归求解24点 */int dfsSolve(double nums[], int n) { // 当只剩一个数时,检查是否为24 if (n == 1) { return fabs(nums[0] - 24.0) < 1e-6; } // 选择两个不同的数进行计算 for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { double a = nums[i], b = nums[j]; double newNums[NUM_COUNT]; int m = 0; // 将剩余的数复制到新数组 for (int k = 0; k < n; k++) { if (k != i && k != j) { newNums[m++] = nums[k]; } } // 尝试所有可能的运算 // 加法 newNums[m] = a + b; if (dfsSolve(newNums, m + 1)) return 1; // 减法 (两种顺序) newNums[m] = a - b; if (dfsSolve(newNums, m + 1)) return 1; newNums[m] = b - a; if (dfsSolve(newNums, m + 1)) return 1; // 乘法 newNums[m] = a * b; if (dfsSolve(newNums, m + 1)) return 1; // 除法 (两种顺序,且除数不能为0) if (fabs(b) > 1e-6) { newNums[m] = a / b; if (dfsSolve(newNums, m + 1)) return 1; } if (fabs(a) > 1e-6) { newNums[m] = b / a; if (dfsSolve(newNums, m + 1)) return 1; } } } return 0;}/* 表达式求值 (使用栈) */double evaluateExpression(char* expr) { double numStack[100]; // 数字栈 char opStack[100]; // 运算符栈 int numTop = -1, opTop = -1; double num = 0; int hasNum = 0; for (int i = 0; expr[i]; i++) { // 处理数字 if (isdigit(expr[i])) { num = num * 10 + (expr[i] - '0'); hasNum = 1; } // 处理运算符 else if (expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/') { if (hasNum) { numStack[++numTop] = num; num = 0; hasNum = 0; } // 处理运算符优先级 while (opTop >= 0 && (opStack[opTop] == '*' || opStack[opTop] == '/') && (expr[i] == '+' || expr[i] == '-')) { char op = opStack[opTop--]; double b = numStack[numTop--]; double a = numStack[numTop--]; switch (op) { case '+': numStack[++numTop] = a + b; break; case '-': numStack[++numTop] = a - b; break; case '*': numStack[++numTop] = a * b; break; case '/': numStack[++numTop] = a / b; break; } } opStack[++opTop] = expr[i]; } // 处理空格 else if (expr[i] == ' ') { if (hasNum) { numStack[++numTop] = num; num = 0; hasNum = 0; } } } // 处理最后一个数字 if (hasNum) { numStack[++numTop] = num; } // 处理剩余运算符 while (opTop >= 0) { char op = opStack[opTop--]; double b = numStack[numTop--]; double a = numStack[numTop--]; switch (op) { case '+': numStack[++numTop] = a + b; break; case '-': numStack[++numTop] = a - b; break; case '*': numStack[++numTop] = a * b; break; case '/': numStack[++numTop] = a / b; break; } } return numTop >= 0 ? numStack[numTop] : 0;}/* 验证表达式是否合法 */int validateExpression(char* expr, int nums[]) { int used[NUM_COUNT] = { 0 }; // 记录数字使用情况 int num = 0; int numCount = 0; for (int i = 0; expr[i]; i++) { // 处理数字 if (isdigit(expr[i])) { num = num * 10 + (expr[i] - '0'); // 检查数字是否在1-10范围内if (num > 10 || num < 1) { return 0; } // 检查数字是否在给定的四个数中 int found = 0; for (int j = 0; j < NUM_COUNT; j++) { if (num == nums[j] && !used[j]) { used[j] = 1; found = 1; break; } } if (!found) return 0; numCount++; } // 遇到运算符或空格时重置数字 else if (expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/' || expr[i] == ' ') { num = 0; } } // 检查是否使用了所有四个数字 for (int i = 0; i < NUM_COUNT; i++) { if (!used[i]) return 0; } return numCount == NUM_COUNT;}/* 计算得分 */int calculateScore(time_t start, time_t end, Difficulty diff) { int timeUsed = (int)difftime(end, start); int timeLimit = (int)diff; // 超过时间限制得0分 if (timeUsed > timeLimit) { return 0; } // 得分公式:基础分100分,按用时比例扣分 return 100 - (timeUsed * 100) / (timeLimit * 2);}/* 更新高分榜 */void updateHighScores(char* name, int score) { // 如果高分榜未满或分数高于最低分 if (numHighScores < MAX_HIGH_SCORES || score > highScores[MAX_HIGH_SCORES - 1].score) { // 添加到高分榜 if (numHighScores < MAX_HIGH_SCORES) { numHighScores++; } // 找到插入位置 int pos = numHighScores - 1; while (pos > 0 && score > highScores[pos - 1].score) { highScores[pos] = highScores[pos - 1]; pos--; } // 插入新记录 strcpy(highScores[pos].name, name); highScores[pos].score = score; // 保存高分榜 saveHighScores(); }}/* 加载高分榜 */void loadHighScores() { FILE* file = fopen("highscores.dat", "rb"); if (file) { fread(&numHighScores, sizeof(int), 1, file); if (numHighScores > MAX_HIGH_SCORES) numHighScores = MAX_HIGH_SCORES; fread(highScores, sizeof(HighScore), numHighScores, file); fclose(file); }}/* 保存高分榜 */void saveHighScores() { FILE* file = fopen("highscores.dat", "wb"); if (file) { fwrite(&numHighScores, sizeof(int), 1, file); fwrite(highScores, sizeof(HighScore), numHighScores, file); fclose(file); }}/* 清屏函数 (兼容不同环境) */void clearScreen() {#ifdef _WIN32 system("cls");#else system("clear");#endif}
12-04
任务描述:本任务要求设计一款简单版本的24点游戏,仅使用1至10之间的数字。游戏需要能够提供四个随机数,并判断玩家是否能够通过运算得出24点。此外,游戏还需要读取玩家输入的表达式并验证其正确性。 功能要求: 1.游戏需要实现记分功能,计算从出题到玩家输入答案的时间,超过一定时间未给出答案则取消该轮,每轮有3次机会,最后将3次分数相加以确定前三名。 2.游戏参与者首先需要输入他们的名称,然后游戏开始。程序会随机生成四张牌(1至10之间的数值),然后玩家需要尽快给出一个表达式,只能使用加号、减号、乘号、除号和括号,不能使用小数运算。例如,如果机器生成的四个数为3、3、6、2,玩家输入表达式:(3+3-2)×6,程序会检查运算是否成功,然后计算所用的时间。如果生成的四个数不能通过运算得出24,例如1、2、1、3,玩家需要输入"NO",然后程序会进入下一题,但正确判断也会记分。每轮游戏进行3次,总分计算在最后。 3.游戏会根据出题到答题的时间限制来设置难度级别,这可以由玩家自行调整。(可选) 4.设计一个算法来判断给定的四个数是否可以通过运算得出24,这是关键的一部分,用于验证玩家是否正确判断"NO",如果判断错误,游戏这一轮结束。 选做要求: 设计游戏进入界面,提供游戏难度设置、高手总分查询和进入/退出游戏选项。 其他要求: 1.界面设计要美观,交互要方便。 2.提供详细的注释:每个变量都需要有注释说明其用途,每个函数都需要注释说明其功能,参数和返回值也需要以注释形式说明其用途,同时需要有注释解释关键的代码段。 3.程序结构清晰,易于阅读。 4.变量和函数的命名要符合规范。 那个代码不能满足要求,请你在此基础上修改一下
12-13
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值