Last active
October 11, 2015 01:28
-
-
Save jysperm/3781877 to your computer and use it in GitHub Desktop.
24点
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <cmath> | |
#include <sstream> | |
using namespace std; | |
/* | |
该程序规则: | |
任意选取 4 个整数,使用加,减,乘,除,括号,运算得到 24. | |
*/ | |
// 最大允许的误差 | |
const double maxDeviation = 0.00001; | |
// 最终结果 | |
const double finalResult = 24; | |
enum Operators | |
{ | |
// 表示四个运算符 | |
opAdd, opMinus, opTimes, opDivide | |
}; | |
// 用于从enum Operators转换到字符串 | |
const char opToStr[] = {'+', '-', '*', '/'}; | |
enum Order | |
{ | |
// 操作数的结合方式,即括号的位置 | |
odFirstToSecond, odSecondToThird, odThirdToFourth | |
}; | |
// 输入的四个数字 | |
int a, b, c, d; | |
// 当前搜索路径的三个运算符 | |
Operators op[3]; | |
// 当前搜索路径的操作数结合方式 | |
Order order[3]; | |
string intToString(int i) | |
{ | |
// 转换 int 为string | |
stringstream ss; | |
ss<<i; | |
return ss.str(); | |
} | |
double calc(Operators op, double a, double b) | |
{ | |
//按照给定的运算符计算结果 | |
switch(op) | |
{ | |
case opAdd: | |
return a + b; | |
case opMinus: | |
return a - b; | |
case opTimes: | |
return a * b; | |
case opDivide: | |
return a / b; | |
} | |
return 0; //只是为了去除编译器的警告 | |
} | |
vector<double> calc(vector<double> cards, Operators op, int pos) | |
{ | |
// 对 cards 中第 pos 个数字和第 pos + 1 个数字,按照 op 运算符进行运算, | |
// 并将结果插入原处,返回处理后的cards | |
// 取出两个操作数 | |
double a = cards[pos]; | |
double b = cards[pos + 1]; | |
// 删除两个操作数 | |
cards.erase(cards.begin() + pos); | |
cards.erase(cards.begin() + pos); | |
double reslut=calc(op, a, b); | |
// 将结果插入原处 | |
cards.insert(cards.begin() + pos,reslut); | |
return cards; | |
} | |
void showResult() | |
{ | |
// 显示当前结果 | |
vector<string> strs; | |
strs.push_back(intToString(a)); | |
strs.push_back(intToString(b)); | |
strs.push_back(intToString(c)); | |
strs.push_back(intToString(d)); | |
while(strs.size() != 1) | |
{ | |
string exp; | |
int size = strs.size(); | |
int pos = static_cast<int>(order[size - 2]); | |
string a = strs[pos]; | |
string b = strs[pos+1]; | |
strs.erase(strs.begin() + pos); | |
strs.erase(strs.begin() + pos); | |
// 如果是最后两个数,就不加括号了 | |
if(size != 2) | |
exp = "(" + a + opToStr[op[size - 2]] + b + ")"; | |
else | |
exp = a + opToStr[op[size - 2]] + b; | |
strs.insert(strs.begin() + pos, exp); | |
} | |
cout<<strs[0]<<endl; | |
} | |
void search(vector<double> cards) | |
{ | |
// 搜索主函数,将会递归 4 层,cards.size() 的值将分别为从4到1 | |
// cards 中各项表示剩余待运算的数字 | |
if(cards.size() != 1) | |
{ | |
for(int k = 0; k<static_cast<int>(cards.size()) - 1; k++) | |
{//遍历各种操作数结合方式 | |
for(int i = 0; i < 4; i++) | |
{//遍历四个运算符 | |
//设置当前运算符 | |
op[cards.size() - 2] = static_cast<Operators>(i); | |
//设置当前操作数结合方式 | |
order[cards.size() - 2] = static_cast<Order>(k); | |
//继续搜索 | |
search(calc(cards, static_cast<Operators>(i), k)); | |
} | |
} | |
} | |
else | |
{ | |
if(abs(cards[0] - finalResult) < maxDeviation) | |
showResult(); | |
} | |
} | |
int main() | |
{ | |
while(cin>>a>>b>>c>>d) | |
{ | |
vector<double> cards; | |
cards.push_back(a); | |
cards.push_back(b); | |
cards.push_back(c); | |
cards.push_back(d); | |
search(cards); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment