[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)为了针对 ...
随机推荐
- 聊聊LuaJIT
JIT 什么是JITJIT = Just In Time即时编译,是动态编译的一种形式,是一种优化虚拟机运行的技术. 程序运行通常有两种方式,一种是静态编译,一种是动态解释,即时编译混合了这二者.Ja ...
- Mybatis Generator插件升级版
一.目的: 1. *mapper.java 文件名称 改为*DAO.java2. mapper以及mapper.xml 重复执行,只会覆盖原模板方法,不会覆盖自定义方法3. 实体类添加中文注释 二.步 ...
- 【LeetCode】LeetCode Weekly Contest 16B
2.一个游戏 YouTube MIT 算法课上有详细的讲解 思路是DP. 话说MIT OpenCourseWare 真心不错.应该好好看看,讲的详细生动. Tips: 1.当n是偶数的时候,首先的选择 ...
- 转】 Spark SQL UDF使用
原博文出自于: http://blog.csdn.net/oopsoom/article/details/39401391 感谢! Spark1.1推出了Uer Define Function功能,用 ...
- key-value键值型数据库:Redis
key-value键值型数据库:Redis redis Redis是in-memory型(内存型)的键值数据库,数据在磁盘上是持久的,键类型是字符串,值类型是字符串.字符串集合(Set).sorted ...
- Codeforces_750_C_(二分查找)
C. New Year and Rating time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- [iOS]查看苹果支持的所有字库
有时候,在开发的时候,想换个字体更加优雅的显示.但是不知道苹果本身到底支持了那些字体,怎么办? 没关系,打开这个网址:http://iosfonts.com/ 所见即所得,非常方便,而且还表明了从那个 ...
- Windows下编译64位GSL
GSL (GNU Scientific Library, http://www.gnu.org/software/gsl/)官方并没有提供编译好的Windows版本.首先要保证Windows是64位的 ...
- docker 转载
写的非常好的一篇文章,不知道为什么被删除了. 利用Google快照,做个存档. 快照地址:地址 作者地址:青牛 什么是docker Docker 是一个开源项目,诞生于 2013 年初,最初是 do ...
- java代码完全手写模仿qq登录界面
这是我模仿QQ2015版界面,实现的基本功能有登陆验证,重置等,当然直接复制代码运行是不一样的,还要注意自己插入自己的图片. 结果截图如下所示: import java.awt.BorderLayou ...