解法1,对于任意输入的四个数字,给出一个24点的解法,若无解,则没有输出。

原理参照下图(编程之美原书)

代码如下,仅供参考

// 1.16.cpp : Defines the entry point for the console application.
// #include "stdafx.h"
#include <iostream>
#include<string>
#include "stdio.h"
#include <math.h>
using namespace std; const int CardsNumber = ;//24点有四张卡
const double ErrorThreshold=1E-;//由于舍入误差,需要加入一个误差阈值,误差在一定范围之内为,判断相等
const int ResultValue = ; #define N 4 string result[CardsNumber]={"","","",""};
double number[CardsNumber]={,,,};
bool PointsGame(int n)
{
if(n == )
{
//如果结果为24
//由于舍入误差,应允许一定范围内的误差 if( fabs(number[]-ResultValue)<ErrorThreshold)
{
cout<<result[]<<endl;
//cout<<'1'<<endl;
return true;
}
else
{
return false;
} } for(int i= ;i<n ;i++)
{
for(int j=i+;j<n;j++)
{
double a,b;
string expa,expb; a=number[i];
b=number[j];
number[j]=number[n-]; expa=result[i];
expb=result[j];
result[j]=result[n-]; result[i]='('+ expa +'+'+expb+')';
number[i]=a+b;
if(PointsGame(n-))
return true; result[i]='('+ expa +'-' + expb +')';
number[i]=a-b;
if(PointsGame(n-))
return true; result[i]='('+ expa + '*' + expb +')';
number[i]=a*b;
if(PointsGame(n-))
return true; if(b!=)
{result[i]='('+expa +'/'+ expb +')';
number[i]=a/b;
if(PointsGame(n-))
return true; } number[i]=a;
number[j]=b;
result[i]=expa;
result[j]=expb; }
} return false;
} int _tmain(int argc, _TCHAR* argv[])
{ PointsGame(); return ;
}

解法2,可以返回,输入4个数字的情况下,一共有多少不同的解。

原理如下图(编程之美原书)

书中没有给出代码,分享下我的代码:

// 1.16.cpp : Defines the entry point for the console application.
// #include "stdafx.h"
#include <iostream>
#include<string>
#include "stdio.h"
#include <math.h>
using namespace std; const int CardsNumber = ;
const double ErrorThreshold=1E-;
const int ResultValue = ; #define N 4 class doubleSet//以double数字为内容的集合
{
public: doubleSet()
{ length=;
} doubleSet(double p[],int n)
{
length=n; for(int i=;i<n;i++)
{
content[i]=p[i];
} } bool IsEmpty()
{
if(length== || length>)
return true;
else
return false;
} void Display()//显示该集合
{ //content[length]='\0';
for(int i=;i<length;i++)
printf("%f ",content[i]);
for(int i=;i<length;i++)
cout<<content[i]<<endl; } int GetLength()
{
return length;
} double* Getcontent()
{
return content;
} static doubleSet Union(doubleSet set1,doubleSet set2) //两个集合求交集
{
int num1=set1.length;
int num2=set2.length; if(num1==)
return set2;
else if(num2==)
return set1; double *p1=set1.content;
double *p2=set2.content; bool Repeat=;
for(int i=;i<num2;i++)
{ for(int j=;j<num1;j++)
{
if( *(p2+i)==*(p1+j))
{
Repeat=;
break;
}
}
if(Repeat==)
{
Repeat=;
}
else
{ num1++;
*(p1+num1-)=*(p2+i);
}
} set1.length=num1; for(int i=;i<num1;i++)
set1.content[i]=p1[i]; return set1;
} private:
int length;//length表示集合的长度
double content[];//content代表集合中的内容
}; doubleSet fun(int i);
doubleSet S[]; //定义16个double数字集合 int Mycheck( doubleSet set)//check 最后有多少个结果为24
{
int num=;
double *content=set.Getcontent();
for(int i=;i<set.GetLength();i++)
{
if(fabs(content[i]-ResultValue)<ErrorThreshold)
{
num++;
}
}
cout<<num<<endl;
return num; }
doubleSet Fork(doubleSet set1,doubleSet set2)//通过加减乘除合并两个数字集合为一个数字集合
{ if(set2.IsEmpty())
return set1; if(set1.IsEmpty())
return set2; doubleSet ret;
int retLen=;
double RetContent[];//因为函数结束后,会释放局部变量,所以设置为静态的
//切记不要返回局部变量指着。 double *content1=set1.Getcontent();
double *content2=set2.Getcontent(); for(int i=;i<set1.GetLength();i++)
{
for(int j=;j<set2.GetLength();j++)
{
*(RetContent+retLen++)=content1[i]+content2[j];
*(RetContent+retLen++)=content1[i]-content2[j];
*(RetContent+retLen++)=content2[j]-content1[i];
*(RetContent+retLen++)=content1[i]*content2[j];
if(content2[j]!=)
*(RetContent+retLen++)=content1[i]/content2[j];
if(content1[i]!=)
*(RetContent+retLen++)=content2[j]/content1[i]; }
} return doubleSet(RetContent,retLen);
} void TheGame(doubleSet set)
{
//把i化为 2进制的数,第j位数为1的代表出现第j个数。
int n=set.GetLength(); //for(int i=1;i<=pow(2,n);i++)
double *content1= set.Getcontent(); static double temp[][];
for(int i=;i<n;i++)//先构造2的指数倍
{
temp[i][] = content1[i];
S[static_cast<int>(pow(2.0,i))]=doubleSet(temp[i],);
}
for(int i=;i<=pow(2.0,n)-;i++)
S[i]=fun(i);//fun返回该集合数字,通过四则运算可以返回的所有结果 Mycheck( S[static_cast<int> (pow(2.0,n)-) ] );
} doubleSet fun(int i)
{
if(!S[i].IsEmpty())
return S[i]; for(int x=;x<i;x++)
{
if((x&i)==x)
S[i]=doubleSet::Union(S[i],Fork(fun(x),fun(i-x)));
}
return S[i];
} int _tmain(int argc, _TCHAR* argv[])
{ double a[]={,,,}; doubleSet set1=doubleSet(a,); TheGame(set1); return ;
}

注:本文主要参考编程之美,1.16节给出的理论,主要目的是把代码贴出来给大家分享

本文的图都来自《编程之美》

本人水平有限,怀着分享学习的态度发表此文,欢迎大家批评,交流。感谢您的阅读。
欢迎转载本文,转载时请附上本文地址:http://www.cnblogs.com/Dzhouqi/p/3362259.html
另外:欢迎访问我的博客 http://www.cnblogs.com/Dzhouqi/

24点C++程序实现 编程之美1.16的更多相关文章

  1. 编程之美2014挑战赛 复赛 Codehunt平台试题答案

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  2. Python编程之美:最佳实践指南PDF高清完整版免费下载|百度云盘|Python新手到进阶

    百度云盘:Python编程之美:最佳实践指南PDF高清完整版免费下载 提取码:1py6 内容简介 <Python编程之美:最佳实践指南>是Python用户的一本百科式学习指南,由Pytho ...

  3. LeetCode:Climbing Stairs(编程之美2.9-斐波那契数列)

    题目链接 You are climbing a stair case. It takes n steps to reach to the top. Each time you can either c ...

  4. 编程之美2.5:寻找最大的K个数

    编程之美2.5:寻找最大的K个数 引申:寻找第k大的数: 方法一: // 选择第k大的数(通过改进快速排序来实现) public static void SelectShort(int[] array ...

  5. 2017“编程之美”终章:AI之战勇者为王

    编者按:8月15日,第六届微软“编程之美”挑战赛在选手的火热比拼中圆满落下帷幕.“编程之美”挑战赛是由微软主办,面向高校学生开展的大型编程比赛.自2012年起,微软每年都在革新比赛命题.紧跟时代潮流, ...

  6. 编程之美Q1

    题目 和数书页有点类似,就直接数吧 #include<iostream> using namespace std; class q1 { public: size_t func(size_ ...

  7. 生成CPU使用率 sin 曲线 控制cpu使用率 编程之美

    入职Oracle 以后想着把之前写过的<编程之美>中控制CPU使用率曲线的程序再写一边, 可是总是由于入职须要学习的东西太多, 没有时间. 程序早就写好了. 最终有机会贴出来了.o(∩∩) ...

  8. 数学之美?编程之美?数学 + 编程= unbelievable 美!

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:Rusu 导语 相信大家跟我一样,偶尔会疑惑:曾经年少的时候学习过的那么多的复杂的数学函数,牛逼的化学方程式,各种物理原理.公式,到底有 ...

  9. hihocoder 微软编程之美2015 初赛 第二场(暴力+字典序+图论+思维算法)

    题目1 : 扑克牌 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 一副不含王的扑克牌由52张牌组成,由红桃.黑桃.梅花.方块4组牌组成,每组13张不同的面值.现在给定52 ...

随机推荐

  1. C++运用SDK截屏

    引言 最近有一个需要截取当前屏幕,并保存成BMP文件的需求.整个需求,拆分成三步:1.截取屏幕,获得位图数据.2.配合bmp文件结构信息,将数据整合.3.对整合后的数据做操作,如保存在本地.通过网络传 ...

  2. 九度OJ 1541 二叉树【数据结构】

    题目地址:http://ac.jobdu.com/problem.php?pid=1541 题目描述: 旋转是二叉树的基本操作,我们可以对任意一个存在父亲节点的子节点进行旋转,包括如下几种形式(设被旋 ...

  3. java学习笔记_MIDI_GUI

    import javax.sound.midi.*; import javax.swing.*; import java.awt.event.*; import java.awt.*; class M ...

  4. ◆◆◆◆◆◆◆◆◆◆◆linux下软件包的管理◆◆◆◆◆◆◆◆◆◆◆◆◆◆

    查看与制定的路径名相匹配的软件包 [root@localhost certs]# which ls alias ls='ls --color=auto' /bin/ls [root@localhost ...

  5. JS判断设备终端(PC,iPad,iPhone,android,winPhone)和浏览器

    JS判断设备终端(PC,iPad,iPhone,android,winPhone)和浏览器 var ua = navigator.userAgent; var browser = {}, weixin ...

  6. [译]深入理解JVM

    深入理解JVM 原文链接:http://www.cubrid.org/blog/dev-platform/understanding-jvm-internals 每个使用Java的开发者都知道Java ...

  7. 转 IHttpModule不起作用

    在 Visual Studio 中,测试 IHttpModule(httpModules) 正常,但是放到服务器上去就不起作用了,这多半得多服务器 IIS 配置入手. 一.看“应用程序池”的“托管管道 ...

  8. Python urllib2多进程共享cookies

    如果想多个进程共享同一个cookies,不用每个进程都重新登录,可以就cookies保存到一个文件,然后多个进程直接共享一个锁来实现 1.一个进程登录完成后,把cookies保存到一个文件里面 sel ...

  9. android include中的控件调用

    项目中经常会有一些布局是重用的,但是如何来更好的利用这些布局中的控件 转: http://zhidao.baidu.com/link?url=GU93U8Wu31dfp7mKEx52hMJkxjFLC ...

  10. EXTJS 4.2 资料 控件之textfield文本框加事件的用法

    { xtype: "textfield", width: 100, id: "txtGroupName", name: "txtGroupName&q ...