[24点计算器][C++版本]无聊拿去玩
特性:数字数量、目标答案不限,当然数据大了会很慢...
基本可以去除所有本质相同的表达式...至少能等出结果的数据规模可以。。
安卓:http://yun.baidu.com/s/1slCGILn
程序用法:
输入n,tar,lim;分别表示n个数,目标答案,最多计算lim个解(0表示输出所有解)
然后输入n个数字
例: 4 24 3
1 2 3 4
表示4个数字1,2,3,4要算出24的前三个解
一般6个数找所有答案开O2需要一分半吧。。
思路(当然是爆枚咯。。。):
由于中缀表达式枚举括号比较麻烦,所以用后缀表达式枚举运算符,最后再把后缀转成中缀输出即可。
但这样还枚举不全,需要枚举数字的全排列再把运算符填进去。
这样虽然可以枚举所有情况,但是因为交换律的存在大量重复出现(比如2*3*4 3*2*4...)所以要去重。。
由于本人能力有限,,所以用了奇怪的方法,,不过效果还不错,方法如下。
随机生成若干个(程序里是4个)数组,和原数组匹配,然后用同样的运算符计算各个数组,把答案打包存进map有重复不输出即可
例:
比如当前枚举的运算方法是(a+b)/c*d
原数组:
w x y z ==>(w+x)/y*z
随机数组:
a[0][] a[0][] a[0][2] a[0][3] ==>(a[0][]+a[0][])/a[0][2]*a[0][3]=A
a[1][] a[1][] a[1][2] a[1][3] ==>(a[1][]+a[1][])/a[1][2]*a[1][3]=B
a[2][] a[2][] a[2][2] a[2][3] ==>(a[2][]+a[2][])/a[2][2]*a[2][3]=C
......
把{A,B,C,....}放到map里
当枚举到(b+a)/c*d的时候发现
x w y z ==>(x+w)/y*z
a[0][] a[0][] a[0][2] a[0][3] ==>(a[0][]+a[0][])/a[0][2]*a[0][3]=D
a[1][] a[1][] a[1][2] a[1][3] ==>(a[1][]+a[1][])/a[1][2]*a[1][3]=E
a[2][] a[2][] a[2][2] a[2][3] ==>(a[2][]+a[2][])/a[2][2]*a[2][3]=F
此时{A,B,C,...}=={D,E,F,...}说明(a+b)/c*d和(b+a)/c*d是同样的表达式,那么不输出即可。
代码如下
#include <bits/stdc++.h> using namespace std; const int base=; int n,a[],vec[],tar,trw=,Cnt;
int test[][],testb[][];
bool visited[]; const char op_list[]={'+','-','*','/'}; struct T
{
double aa,bb;
bool operator<(const T temp)const
{
if(fabs(aa-temp.aa)>1e-) return aa<temp.aa;
if(fabs(bb-temp.bb)>1e-) return bb<temp.bb;
return false;
}
}; struct Expr
{
string str;
char op;
Expr(){op=' ';}
}; vector<int> op[];
map<T,bool> Map; void Init_random_list()
{
srand(time());
for(int j=;j<;++j) for(int i=;i<n;++i) test[i][j]=rand()%(base*);
for(int i=;i<n;++i) for(int j=i+;j<n;++j)
if(a[i]==a[j]) for(int k=;k<;++k) test[j][k]=test[i][k];
return ;
}
double C()
{
stack<double> S;
stack<double> r[];
for(int i=;i<n;++i)
{
S.push(vec[i]);
for(int j=;j<(int)op[i].size();++j)
{
double t1=S.top(); S.pop();
double t2=S.top(); S.pop();
if(op[i][j]==) S.push(t2+t1);
if(op[i][j]==) S.push(t2-t1);
if(op[i][j]==) S.push(t2*t1);
if(op[i][j]==) S.push(t2/t1);
}
}
if(fabs(S.top()-(double)tar)<1e-)
{
for(int i=;i<n;++i)
{
for(int k=;k<;++k)
{
r[k].push(testb[i][k]);
for(int j=;j<(int)op[i].size();++j)
{
double t1=r[k].top(); r[k].pop();
double t2=r[k].top(); r[k].pop();
if(op[i][j]==) r[k].push(t2+t1);
if(op[i][j]==) r[k].push(t2-t1);
if(op[i][j]==) r[k].push(t2*t1);
if(op[i][j]==) r[k].push(t2/t1);
}
}
}
T temp=(T){r[].top(),r[].top()};
if(Map[temp])return -1e100;
Map[temp]=true;
}
return S.top();
} void Pr()
{
Cnt++; Expr temp;
stack<Expr> S; for(int i=;i<n;++i)
{
char temp_str[];
sprintf(temp_str,"%d",vec[i]);
temp.str=temp_str;
temp.op=' '; S.push(temp);
for(int j=;j<(int)op[i].size();++j)
{
Expr t1,t2;
t2=S.top(); S.pop();
t1=S.top(); S.pop();
if(op[i][j]> && (t1.op=='+' || t1.op=='-' || t2.op=='+' || t2.op=='-'))
{
if(t1.op=='+' || t1.op=='-') t1.str=" ( "+t1.str+" ) ";
if(t2.op=='+' || t2.op=='-') t2.str=" ( "+t2.str+" ) ";
temp.str=t1.str+' '+op_list[op[i][j]]+' '+t2.str;
temp.op=op_list[op[i][j]];
}
else temp.str=t1.str+' '+op_list[op[i][j]]+' '+t2.str,
temp.op=op_list[op[i][j]];
S.push(temp);
}
}
printf("%s\n",S.top().str.c_str());
return ;
} /* Violent enumeration operator */
void Calc(const int step,const int pos,const int lim)
{
if(step==n-)
{
if(fabs(C()-(double)tar)<1e-)
{
Pr();
if(Cnt==trw)throw ;
}
return ;
}
for(int i=max(pos,step+);i<n;++i)
{
for(int j=;j<=lim;++j)
{
op[i].push_back(j);
if(step+<=i) Calc(step+,i,lim);
op[i].pop_back();
}
}
return ;
} /* Violent enumeration Permutations */
void Dfs(const int step,const int lim)
{
if(step==n)
{
try{Calc(,,lim);}
catch(...){throw ;}
return ;
}
for(int i=;i<n;++i)
{
if(!visited[i])
{
visited[i]=true;
vec[step]=a[i];
for(int j=;j<;++j)
testb[step][j]=test[i][j];
Dfs(step+,lim);
visited[i]=false;
}
}
return ;
} int main()
{
printf("Size of Input:\t"); scanf("%d",&n);
printf("Target Result:\t"); scanf("%d",&tar);
printf("Result limits(0 for no limits): "); scanf("%d",&trw); printf("Input(32bits integers):\n");
for(int i=;i<n;++i) scanf("%d",&a[i]); clock_t start_time=clock();
Init_random_list(); printf("========================\n");
//这里会优先选择没有乘除的方案
//try{Dfs(0,0);}catch(...){}
//try{Dfs(0,1);}catch(...){}
//try{Dfs(0,2);}catch(...){}
try{Dfs(,);}catch(...){}
printf("========================\n"); printf("%d Results Found!\n",Cnt);
printf("%ldms Cost!\n",clock()-start_time);
return ;
}
[24点计算器][C++版本]无聊拿去玩的更多相关文章
- Mozilla Firefox 24.0 Beta 5 发布
Mozilla今天将Firefox 24.0 Beta 5版本放到了FTP的release目录,新版开始全面支持OS X 10.7全新的滚动条样式,禁止网站插件运行的功能出现在任务栏左侧,调整了界面U ...
- 0316-复利计算器3.0---release
目录 一.项目简介 二.Github链接推送 三.客户需求 四.需求分析 五.项目设计 六.完成效果 七.JUnit ...
- 0406.复利计算器5.0版-release
复利计算器5.0-release 目录 项目简介 Github链接推送 客户需求 新增需求分析 项目设计 效果演示 操作说明 程序结构 结对分工 合作照片 总结 1.项目简介 项目名称:复利计算器 目 ...
- 0414-复利计算器6.0.Release
复利计算器6.0--Release 前言 本次复利计算器的版本更新,主要有以下内容的完善: 1.优化了Web版的页面,提供了更舒服美观的用户体现. 2.新增了移动端(安卓)app版本. 版本信息 项目 ...
- PhoneGap搭建运行环境(3.2版本)
一. 1.准备环境nodejs(http://nodejs.org/download/) 2.ant(http://ant.apache.org/bindownload.cgi) 3.Android ...
- eclipse版本选择
Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环境,2001年11月贡献给开源社区,现在它由非营利软件供应商联盟Eclipse基金会. Ec ...
- 微信小程序计算器Bug版=-=(笔记)
微信小程序计算器BUG版本 无APPID的测试号登录,先在app.json中更改路径,以及修改头部信息. 首先一个输入框字段用{{screenData}} 功能可以退格,清屏,正负号,正常操作加减乘除 ...
- CentOS7编译安装MySQL5.7.24
目录 安装依赖 安装boost 编译安装MySQL 配置 登录MySQL,修改密码 安装依赖 (1)cmake是新版MySQL的编译工具 sudo yum install gcc gcc-c++ pc ...
- Android 6.0 7.0 8.0 一个简单的app内更新版本-okgo app版本更新
登陆时splash初始页调用接口检查app版本.如有更新,使用okGo的文件下载,保存到指定位置,调用Android安装apk. <!-- Android 8.0 (Android O)为了针对 ...
随机推荐
- P3822 [NOI2017]整数
传送门 shadowice大佬已经写的非常详细了我就不再写一遍了-- //minamoto #include<bits/stdc++.h> #define u unsigned int # ...
- [TJOI2012]桥
Description 有n个岛屿,m座桥,每座桥连通两座岛屿,桥上会有一些敌人,玩家只有消灭了桥上的敌人才能通过,与此同时桥上的敌人会对玩家造成一定伤害.而且会有一个大Boss镇守一座桥,以玩家目前 ...
- Storm编程入门API系列之Storm的定时任务实现
概念,见博客 Storm概念学习系列之storm的定时任务 Storm的定时任务,分为两种实现方式,都是可以达到目的的. 我这里,分为StormTopologyTimer1.java 和 Sto ...
- Kafka~服务端几个常用的命令
在Centos上安装和部署完成kafka之后,我们就可以向服务端推消息和消费它了,今天主要聊几个常用的命令,比建立topic,从broken显示所有topics列表,向broken发消息,从broke ...
- [转]ASP.NET MVC的帮助类HtmlHelper和UrlHelper
本文转自:http://www.cnblogs.com/greatandforever/archive/2010/04/20/1715914.html?login=1 在ASP.NET MVC框架中没 ...
- NodeJS、NPM安装配置步骤
安装NodeJS和NPM 1.Node JS 官网下载地址 https://nodejs.org/en/download/ 2.安装完后,使用cmd 命令输入两个命令,查看安装状态 node -v n ...
- Angular——作用域
基本介绍 应用App是无法嵌套的,但是controller是可以嵌套的,每个controller都会对应一个模型(model)也就是$scope对象,不同层级的controller下的$scope遍产 ...
- Probabilistic locking in SQLite
In SQLite, a reader/writer lock mechanism is required to control the multi-process concurrent access ...
- spring中配置数据源
spring中配置数据源的几种常见方式: #mysql 数据库配置(jdbc.properties) jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.u ...
- Spartan6系列之芯片配置模式详解
1. 配置概述 Spartan6系列FPGA通过把应用程序数据导入芯片内部存储器完成芯片的配置.Spart-6 FPGA可以自己从外部非易失性存储器导入编程数据,或者通过外界的微处理器.DSP等对 ...