[深搜回溯]24点

作者: 肥宅_Sean | 来源:发表于2017-11-01 12:36 被阅读0次

题目描述:
24点是一个有趣的扑克牌游戏。发4张牌,然后计算是否能够算出24点来。(不考虑有括号的算式,输出计算式将从左到有进行计算)
如果可以,输出算数表达式;
如果不可以,输出NONE
如果表达式中,有错误输入,输出“ERROR”
输入实例:
2
AAAA
Q3J8
输出实例:
NONE
Q-J*3*8

代码解析:
下面解析,将以对其中一组数据(4个字符)为例

  1. main函数中读入字符串
  2. 先选择第一个数
  3. 开始深搜,一直到搜了四个数之后,判断是否为24,是就将更新答案,并返回True
  4. 进行选择,每一次深搜,都是选择一个运算符和一个数字(字符)。用tempAns来记录表达式。
  5. 注意要对深搜部分进行恢复,避免影响下一次深搜。同时用visited记录访问过的点,避免重复使用,并进入死循环。(答案错了就检查是不是没有深搜恢复好;出现死循环,很有可能是因为没有标记访问过的点)
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

char cards[4];
bool visited[4];
char cal[] = {'+', '-', '*', '/'};
string ans, tempAns;
double tempNum;
int charToNum(char c) {
    if (c <= '9' && c>= '0') {
        return c - '0';
    } else if (c == 'J') {
        return 11;
    } else if (c == 'Q') {
        return 12;
    } else if (c == 'K') {
        return 13;
    } else if (c == 'A') {
        return 1;
    }
    return -1;
}
bool DFS(int now) { // now From 1
    if(now == 4) {
        if (abs(tempNum - 24) < 1e-6) {
            ans = tempAns;
            return true;
        } 
        return false;
    }
    // choose a cal
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (!visited[j]) {
                if (i == 0) {
                    tempNum += charToNum(cards[j]);
                    visited[j] = true;
                    tempAns.push_back(cal[i]);
                    tempAns.push_back(cards[j]);
                } else if (i == 1) {
                    tempNum -= charToNum(cards[j]);
                    visited[j] = true;
                    tempAns.push_back(cal[i]);
                    tempAns.push_back(cards[j]);
                } else if (i == 2) {
                    tempNum *= charToNum(cards[j]);
                    visited[j] = true;
                    tempAns.push_back(cal[i]);
                    tempAns.push_back(cards[j]);
                } else if (i == 3) {
                    tempNum /= charToNum(cards[j]);
                    visited[j] = true;
                    tempAns.push_back(cal[i]);
                    tempAns.push_back(cards[j]);
                }
                
                if(DFS(now + 1)) {
                    return true;
                }
                
                if (i == 0) {
                    tempNum -= charToNum(cards[j]);
                    visited[j] = false;
                    tempAns = tempAns.substr(0, tempAns.length() - 2);
                } else if (i == 1) {
                    tempNum += charToNum(cards[j]);
                    visited[j] = false;
                    tempAns = tempAns.substr(0, tempAns.length() - 2);
                } else if (i == 2) {
                    tempNum /= charToNum(cards[j]);
                    visited[j] = false;
                    tempAns = tempAns.substr(0, tempAns.length() - 2);
                } else if (i == 3) {
                    tempNum *= charToNum(cards[j]);
                    visited[j] = false;
                    tempAns = tempAns.substr(0, tempAns.length() - 2);
                }
            }
        }
    }
    return false;
}

int main(){
    int time, fa;
    cin >> time;
    while(time--) {
        char c;
        fa  = true;
        for (int i = 0; i < 4; ++i){
            cin >> c;
            if (c <= '9' && c>= '0' || c == 'J'  || c == 'Q' || c == 'K' || c == 'A') {
                cards[i] = c;
            } else {
                fa = false;
            }
        }
        if (!fa) {
            cout << "Error!\n"; continue;
        }
        memset(visited, false, sizeof(visited));
        
        bool ok = false;
        for (int i = 0; i < 4; ++i) {
            tempAns.clear();
            
            visited[i] = true;
            tempAns.push_back(cards[i]);
            
            tempNum = charToNum(cards[i]);
            if (DFS(1)){
                cout<< ans<< endl;
                ok =  true;
                break;
            }
            visited[i] = false;
        }
        if (!ok) {
            cout << "NONE\n";
        }
    }
}

相关文章

  • 深度搜索与回溯

    深度搜索与回溯法的区别 回溯法 = 深搜 + 剪枝。一般大家用深搜时,或多或少都会剪枝。深搜一般用递归实现,比较简...

  • 47. 全排列 II

    思路 排序,人为规定顺序去重。 深搜+回溯

  • [深搜回溯]24点

    题目描述:24点是一个有趣的扑克牌游戏。发4张牌,然后计算是否能够算出24点来。(不考虑有括号的算式,输出计算式将...

  • 【洛谷 P1219】八皇后

    八皇后(题目链接) 思路 典型的深搜回溯问题 代码

  • 深搜回溯(八皇后,单词方阵)

    1.要说八皇后问题,具体问题就不在描述了第一种:用矩阵存储棋盘map[n][n]:一行一行(或一列一列)放棋子。代...

  • 算法08-回溯法:面试最常见问题

    算法08-回溯法:面试最常见问题 一、介绍 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜...

  • 回溯

    回溯算法 1.回溯法的简介 回溯法就是在尝试穷举搜素的同时,当发现某一步走不通时,可以回退到前一步,继续寻找问题的...

  • 数据结构与算法-DFS/回溯

    回溯backtracking 回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜...

  • CCF201512-3 画图(Java)

    深搜会爆栈的一道题(90分),宽搜可以过(100分) 深搜代码

  • 选书(深搜)

    问题描述 n个同学分n本书,每个人都有自己喜欢的书(即a[i][j]==1),求出所有的分配方案

网友评论

    本文标题:[深搜回溯]24点

    本文链接:https://www.haomeiwen.com/subject/srnwpxtx.html