【回溯 代数系统】679. 24 点游戏

本文涉及知识点

回溯 代数系统

LeetCode679. 24 点游戏

给定一个长度为4的整数数组 cards 。你有 4 张卡片,每张卡片上都包含一个范围在 [1,9] 的数字。您应该使用运算符 [‘+’, ‘-’, ‘*’, ‘/’] 和括号 ‘(’ 和 ‘)’ 将这些卡片上的数字排列成数学表达式,以获得值24。
你须遵守以下规则:
除法运算符 ‘/’ 表示实数除法,而不是整数除法。
例如, 4 /(1 - 2 / 3)= 4 /(1 / 3)= 12 。
每个运算都在两个数字之间。特别是,不能使用 “-” 作为一元运算符。
例如,如果 cards =[1,1,1,1] ,则表达式 “-1 -1 -1 -1” 是 不允许 的。
你不能把数字串在一起
例如,如果 cards =[1,2,1,2] ,则表达式 “12 + 12” 无效。
如果可以得到这样的表达式,其计算结果为 24 ,则返回 true ,否则返回 false 。
示例 1:
输入: cards = [4, 1, 8, 7]
输出: true
解释: (8-4) * (7-1) = 24
示例 2:
输入: cards = [1, 2, 1, 2]
输出: false

提示:

cards.length == 4
1 <= cards[i] <= 9

回溯、代数系统:错误

枚举cards的所有排列。每种排列的两张卡牌直接枚举加减乘除。从左向右向右运行,可以理解为加了括号。
比如:c1,c2,c3,c4 ,((c1?c2)?c3)?c4 ?表示运算符。
可以用分数(pair) 组成代数系统,任何结果都可以用a+b*c表示。
初始:{0,1,c1}
加法: {a+b × \times ×c,1,x}
减法:{a+b × \times ×c,-1,x}
乘法:{a,b × \times ×c,x}
除法:{a,b × \times ×c, 1 x \frac {1} {x } x1}

错误原因

6/(1 - 3/4) 无法用代数系统表示

核心代码

class Solution {
public:bool judgePoint24(vector<int>& cards) {sort(cards.begin(), cards.end());do {int hasDo = 0;std::function<void(pair<int, int>, pair<int, int>, pair<int, int>)> BackTrack = [&](pair<int, int> a, pair<int, int> b, pair<int, int>c ){if (3 == hasDo) {auto res = Cal(a, b, c);m_bRes |= Is(res);return ;}auto x = cards[hasDo + 1];hasDo++;BackTrack(Cal(a, b, c), { 1,1 }, { x,1 });BackTrack(Cal(a, b, c), { -1,1 }, { x,1 });BackTrack(a, Mul(b,c), { x,1 });BackTrack(a, Mul(b, c), { 1,x });hasDo--;};BackTrack({ 0,1 }, { 1,1 }, { cards[0],1 });} while (next_permutation(cards.begin(), cards.end()));return m_bRes;}pair<int, int> Mul(const pair<int, int>& a, const pair<int, int>& b) {return { a.first * b.first,a.second * b.second };}pair<int, int> Cal(const pair<int, int>& a, const pair<int, int>& b, const pair<int, int>& c) {auto d = Mul(b,c);	if ((0 == d.second) || (0 == a.second)) { return { 1,0 }; }return {a.first*d.second +d.first*a.second,d.second *a.second};}bool Is(const pair<int, int>& a) {if (0 == a.second) { return false; }return a.second * 24 == a.first;}bool m_bRes = false;
};

回溯

4个任意选两个数,考虑顺序。也就是P 4 2 _4^2 42。枚举4个运算符。4个数变成48种3个数。
从任意三个数中选择2个,由于考虑顺序,有6种可能。枚举4种运算符,也就是24种。
对于任意两个数,考虑顺序,有2个选择可能。枚举4种运算符,也就是8种可能。
总时间复杂度:O(48248) < O(105)

代码

class Solution {
public:bool judgePoint24(vector<int>& cards) {std::function<void(vector<pair<int, int>>&)> BackTrack = [&](vector<pair<int, int>>& card){if (1 == card.size()) {		m_bRes |= Is(card[0]);return;}for (int i = 0; i < card.size(); i++) {for (int j = 0; j < card.size(); j++) {if (i == j) { continue; }vector<pair<int, int>> tmp;for (int k = 0; k < card.size(); k++) {if ((k == i) || (k == j)) { continue; }tmp.emplace_back(card[k]);}tmp.emplace_back(make_pair( 0,0));tmp.back() = Mul(card[i], card[j]);BackTrack(tmp);tmp.back() = Mul(card[i], { card[j].second,card[j].first });BackTrack(tmp);tmp.back() = Add(card[i], card[j]);BackTrack(tmp);tmp.back() = Add(card[i], { -card[j].first,card[j].second });BackTrack(tmp);}}};vector<pair<int, int>> card = { {cards[0],1},{cards[1],1},{cards[2],1},{cards[3],1} };BackTrack(card);return m_bRes;}pair<int, int> Mul(const pair<int, int>& a, const pair<int, int>& b) {return { a.first * b.first,a.second * b.second };}pair<int, int> Add(const pair<int, int>& a, const pair<int, int>& b) {return { a.first * b.second + b.first * a.second,b.second * a.second };}bool Is(const pair<int, int>& a) {if (0 == a.second) { return false; }return a.second * 24 == a.first;}bool m_bRes = false;
};

2023年5月

struct SDecimal
{
SDecimal(int iNum=0, int iDeno = 1)
{
m_iNum = iNum;
m_iDeno = iDeno;
int iGCD = GCD(abs(m_iNum), abs(m_iDeno));
m_iNum /= iGCD;
m_iDeno /= iGCD;
if (m_iDeno < 0)
{
m_iDeno = -m_iDeno;
m_iNum = -m_iNum;
}
}
SDecimal operator*(const SDecimal& o)const
{
return SDecimal(m_iNumo.m_iNum, m_iDenoo.m_iDeno);
}
SDecimal operator/(const SDecimal& o)const
{
return SDecimal(m_iNumo.m_iDeno, m_iDenoo.m_iNum);
}
SDecimal operator+(const SDecimal& o)const
{
const int iGCD = GCD(m_iDeno, o.m_iDeno);
const int iDeno = m_iDenoo.m_iDeno / iGCD;
return SDecimal(m_iNum
(iDeno / m_iDeno) + o.m_iNum*(iDeno / o.m_iDeno), iDeno);
}
SDecimal operator-(const SDecimal& o)const
{
const int iGCD = GCD(m_iDeno, o.m_iDeno);
const int iDeno = m_iDenoo.m_iDeno / iGCD;
return SDecimal(m_iNum
(iDeno / m_iDeno) - o.m_iNum*(iDeno / o.m_iDeno), iDeno);
}
bool operator==(const SDecimal& o)const
{
return (m_iNum == o.m_iNum) && (m_iDeno == o.m_iDeno);
}
bool operator<(const SDecimal& o)const
{
auto tmp = *this - o;
return tmp.m_iNum < 0;
}
int m_iNum=0;//分子
int m_iDeno=1;//分母
};

class Solution {
public:
bool judgePoint24(vector& cards) {
m_cards = cards;

	vector<int> indexs;DFS(indexs);return m_bSuc;
}
void DFS(vector<int>& indexs )
{if (4 == indexs.size()){vector<SDecimal> datas;for (const auto& index : indexs){datas.emplace_back(m_cards[index]);}DFSCal(datas);return;}for (int i = 0; i < 4; i++){if (indexs.end() != std::find(indexs.begin(), indexs.end(), i)){continue;}indexs.emplace_back(i);DFS(indexs);indexs.pop_back();}
}
void DFSCal(const vector<SDecimal>& datas)
{if ((1 == datas.size()) && (datas[0] == 24 )){m_bSuc = true;return;}vector<SDecimal> vRet;for (int i = 0; i + 1 < datas.size(); i++){vector<SDecimal> vParam;for (int j = 0; j < i; j++){vParam.emplace_back(datas[j]);}vParam.emplace_back(0);for (int j = i + 2; j < datas.size(); j++){vParam.emplace_back(datas[j]);}vParam[i] = datas[i] * datas[i + 1];DFSCal(vParam);if (0 != datas[i + 1].m_iNum){vParam[i] = datas[i] / datas[i + 1];DFSCal(vParam);}			vParam[i] = datas[i] + datas[i + 1];DFSCal(vParam);vParam[i] = datas[i] - datas[i + 1];DFSCal(vParam);}
}
vector<int> m_cards;
bool m_bSuc = false;

};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
《喜缺全书算法册》以原理、正确性证明、总结为主。
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/837490.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQLserver - 笔记

1 SQLserver - 用户管理 4、SQL SERVER数据库用户管理_哔哩哔哩_bilibili 创建用户 - user 2.选择用户&#xff0c;修改属性

Qt---绘图和绘图设备

一、QPainter绘图 绘图事件 void paintEvent() 声明一个画家对象&#xff0c;OPainter painter(this) this指定绘图设备 画线、画圆、画矩形、画文字 设置画笔QPen 设置画笔宽度、风格 设置画刷QBrush 设置画刷风格 代码示例&#xff1a; #includ…

LeetCode---循环队列

循环队列就是只有固定的内存&#xff0c;存数据&#xff0c;出数据&#xff0c;但是也和队列一样&#xff0c;先进先出。如下图所示&#xff0c;这是他的样子 在head出&#xff0c;tail进&#xff0c;但是这个如果用数组解决的话&#xff0c;就有问题&#xff0c;力扣给我们的接…

Building3D An Urban-Scale Dataset and Benchmarks 论文阅读

文章主页 Building3D 任务 提出了一个城市规模的数据集&#xff0c;由超过 16 万座建筑物以及相应的点云、网格和线框模型组成&#xff0c;覆盖爱沙尼亚的 16 个城市&#xff0c;面积约 998 平方公里。 动机 现有的3D建模数据集主要集中在家具或汽车等常见物体上。缺乏建…

CAPL入门之使用CAPL记录测试Logging

0 前言 以往测试的log都是直接从trace导出&#xff0c;但是最近发现trace中能导出的数据是有限的&#xff0c;如果测试的时间过长&#xff0c;新的数据就会把之前的数据全部覆盖&#xff0c;并且对于长时间的测试&#xff0c;直接导出trace的内容也会造成查找效率低下的问题。因…

centos7下使用docker安装fastdfs服务

先查看容器是否已经存在 docker ps -a 删除掉之前的tracker及storage服务 docker rm tracker docker rm storage 1、没有镜像先下载镜像 docker pull morunchang/fastdfs 2、运行服务 a、不指定物理服务器路径 docker run -d --name tracker --nethost morunchang/fastdfs sh…

Java面试八股之String s = “String“;和String s = new String(“String“);有什么区别

Java中String s "String";和String s new String("String");有什么区别 字符串字面量&#xff08;"String"&#xff09;&#xff1a; 常量池&#xff1a;使用字面量方式创建字符串时&#xff0c;Java虚拟机&#xff08;JVM&#xff09;会在运…

Jmeter接口测试之参数化

在接口测试中&#xff0c;某些时候一些场景会使用到参数化的场景&#xff0c;参数化简单的说就是同一个请求需要不同的数据&#xff0c;比如在性能测试中需要并发多个用户的场景&#xff0c;这样的目的是为了模拟真实的用户场景&#xff0c;需要模拟不同的账号&#xff0c;这里…

算法练习第21天|216.组合总和|||、17.电话号码的字母组合

216.组合总和 III 216. 组合总和 III - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/combination-sum-iii/ 题目描述&#xff1a; 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一…

北亚MF2200手机取证平台介绍

一、产品介绍。 北亚MF2200手机取证平台是由北亚企安科技&#xff08;北京&#xff09;有限公司&#xff08;Frombyte&#xff09;自主研发的一款针对智能手机&#xff08;iPhone、Android&#xff09;及 iPad 取证分析的法证平台。本平台采集速度快&#xff0c;可通过自动提取…

【VUE】VUE3绘制箭头组件

效果预览&#xff1a; 长、宽、粗细等等根据情况合理调整即可。 组件&#xff1a; <template><div class"line" :style"props.arrowsColor"></div> </template><script setup> import { defineProps, ref, onMounted } fr…

为什么使用AI 在游戏中不犯法

使用AI在游戏中本身并不违法&#xff0c;甚至在很多情况下&#xff0c;游戏公司自己也会在游戏中集成AI来提高游戏体验&#xff0c;例如通过AI驱动的非玩家角色&#xff08;NPC&#xff09;来增加游戏的互动性和挑战性。然而&#xff0c;使用AI是否违法取决于AI的使用方式和目的…

36. 有效的数独 - 力扣(LeetCode)

基础知识要求&#xff1a; Java&#xff1a;方法、for循环、if判断、数组 Python&#xff1a; 方法、for循环、if判断、列表、集合 题目&#xff1a; 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一…

word2019 64位 NoteExpress突然无法使用解决方法

之前用的好好的&#xff0c;去除格式化运行过一次。 打开别的文档&#xff0c;突然发现红框中的图标全变灰了 根据教程添加 加载项&#xff0c;然后word以管理员身份重启&#xff0c;NE也以管理员身份运行&#xff0c;又可以了 然后突然又不行了&#xff0c;重启电脑后NE变成…

普中STM32F103ZET6开发板让DS0和DS1两个LED同时亮

欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.代码 三.运行效果 一.前言 在这套stm32教程中,只教学了如何亮DS0,而没有教学如何亮DS1。 二.代码 main.c #include "stm32f10x.h"void Syst

flowable多对并发网关跳转的分析

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

spring boot3多模块项目工程搭建-下(团队开发模板)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 目录 写在前面 上文衔接 Common模块 DAO模块 Service模块 Web模块 API模块 写在最后 写在前面 本文介绍了springboot开发后端服务&#xff0c;多模块项目工程搭建&#xff0c;各模块的…

ZL-016D多通道小鼠主动跑轮系统主要研究动物生活节律

简单介绍&#xff1a; 多通道小鼠主动跑轮系统是由动物本身自发运动来推动跑轮转动。在这种构型中&#xff0c;笼内动物长期活动的信息&#xff0c;如跑轮转动方向、转数、累计总行程等&#xff0c;能够使用编码器进行长度计记录。此装置由转轮组件、笼体、以及转动方向速度传…

勒索软件漏洞?在不支付赎金的情况下解密文件

概述 在上一篇文章中&#xff0c;笔者对BianLian勒索软件进行了研究剖析&#xff0c;并且尝试模拟构建了一款针对BianLian勒索软件的解密工具&#xff0c;研究分析过程中&#xff0c;笔者感觉构建勒索软件的解密工具还挺有成就感&#xff0c;因此&#xff0c;笔者准备再找一款…

企业OA办公系统开发笔记:2、MyBatis-Plus

文章目录 企业办公系统&#xff1a;2、MyBatis-Plus一、MyBatis-Plus1、简介2、主要特点3、依赖 二、MyBatis-Plus入门1、配置文件2、启动类3、实体类4、添加Mapper类5、测试Mapper接口6、CRUD测试6.1、insert添加6.1.1、示例6.1.2、主键策略 6.2、更新6.3、删除6.3.1、根据id删…