[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)为了针对 ...
随机推荐
- MySQL索引使用以及优化
优化后台业主评价服务人员运行缓慢. 案发现场:后台业主评价服务人员列表页以及搜索页运行缓慢.运行时间为24074ms. 排查过程: 1.代码开头加时间,结束加时间.看运行了多少秒. 2.给评价 ...
- cloudera-agent启动File not found : /usr/sbin/cmf-agent解决办法(图文详解)
不多说,直接上干货! 问题详情 bigdata@nssa-sensor1:~$ sudo service cloudera-scm-agent startFile not found : /usr/s ...
- Mybatis的Dao向mapper传多个参数(三种解决方案)转自《super超人》
第一种方案 : DAO层的函数方法 Public User selectUser(String name,String area); 对应的Mapper.xml <select id=" ...
- java list遍历三种方法
JSONArray jsonArray = new JSONArray(); jsonArray.add("1"); jsonArray.add("2"); j ...
- Pycharm消除波浪线
PyCharm使用了较为严格的PEP8检查规则,稍微有点错误就会出现波浪线提示.那么怎么消除这些波浪线呢?一个简单粗暴的方法就是:在编辑器的右下角有个小人形状的按钮,点开之后有个滚动条,将滚动条滑动到 ...
- 通俗理解LDA主题模型(boss)
0 前言 看完前面几篇简单的文章后,思路还是不清晰了,但是稍微理解了LDA,下面@Hcy开始详细进入boss篇.其中文章可以分为下述5个步骤: 一个函数:gamma函数 四个分布:二项分布.多项分布. ...
- (转) 淘淘商城系列——使用SolrJ查询索引库
http://blog.csdn.net/yerenyuan_pku/article/details/72908538 我们有必要在工程中写查询索引库的代码前先进行必要的测试.我们先到Solr服务页面 ...
- HDU_1021_费布拉切变形
Fibonacci Again Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- Masonry 原理与使用说明
原理: 1)约束生成:MASConstraintMaker: 2)缺省补齐: - (void)setSecondViewAttribute:(id)secondViewAttribute { if ( ...
- Django框架 之基础入门
django是一款MVT的框架 一.基本过程 1.创建项目:django-admin startproject 项目名称 2.编写配置文件settings.py(数据库配置.时区.后台管理中英文等) ...