华为OJ题目:24点运算
2015-08-14 20:53
483 查看
计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(*), 除(/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王:3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。详细说明:1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,友情提醒,整数除法要当心;2.牌面2~10对应的权值为2~10, J、Q、K、A权值分别为为11、12、13、1;3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;4.输出的算式格式为4张牌通过+-*/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确;5.输出算式的运算顺序从左至右,不包含括号,如1+2+3*4的结果为246.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。输入:输入4张牌为字符串形式,以一个空格隔开,首尾无空格;输出:如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;输出的算式格式为4张牌通过+-*/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确;输出算式的运算顺序从左至右,不包含括号,如1+2+3*4的结果为24如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。解题思路:1,对输入的字符解析成int存储到raw[4]中。2,对raw[]中的四个元素进行全排列(用迭代的方法)。3,三次for循环计算四个元素进行运算后的结果。看代码:
#include <iostream> using namespace std; void permStr(char *str,int i); char allSor[24][5]; char changeToOp(int r); static int k=0; int main(int argc, const char * argv[]) { int i=0; char raw[5]; raw[4]='\0';//后面用到strlen()时,标志元素结束
while (i<4) { cin>>raw[i]; if ((raw[i]>='2'&&(int)raw[i]<='1'+9)) { i++; }else if (raw[i]=='A'){ raw[i]='1'; i++; }else if(raw[i]=='J'){ raw[i]='1'+10; i++; }else if(raw[i]=='Q'){ raw[i]='1'+11; i++; }else if(raw[i]=='K'){ raw[i]='1'+12; i++; }else{ cout<<"ERROR"<<endl; return 0; } } // cout<<strlen(raw)<<endl; permStr(raw,0); double ripe[24][4]; for (int i=0; i<24; i++) { ripe[i][0]=allSor[i][0]-'0'; ripe[i][1]=allSor[i][1]-'0'; ripe[i][2]=allSor[i][2]-'0'; ripe[i][3]=allSor[i][3]-'0'; } int ret=0; for (int i=0; i<24; i++) { for (int a=0; a<3; a++) { for (int b=0; b<3; b++) { for (int c=0; c<3; c++) { switch (a) { case 0: ret=ripe[i][0]+ripe[i][1]; break; case 1: ret=ripe[i][0]-ripe[i][1]; break; case 2: ret=ripe[i][0]*ripe[i][1]; break; case 3: ret=ripe[i][0]/ripe[i][1]; break; default: break; } switch (b) { case 0: ret+=ripe[i][2]; break; case 1: ret-=ripe[i][2]; break; case 2: ret*=ripe[i][2]; break; case 3: ret/=ripe[i][2]; break; default: break; } switch (c) { case 0: ret+=ripe[i][3]; break; case 1: ret-=ripe[i][3]; break; case 2: ret*=ripe[i][3]; break; case 3: ret/=ripe[i][3]; break; default: break; } if (ret==24) { cout<<ripe[i][0]<<changeToOp(a)<<ripe[i][1]<<changeToOp(b)<<ripe[i][2]<<changeToOp(c)<<ripe[i][3]<<endl; return 0; } } } } } cout<<"NONE"<<endl; return 0; } char changeToOp(int r){ char op; switch (r) { case 0: op='+'; break; case 1: op='-'; break; case 2: op='*'; break; case 3: op='/'; break; default: break; } return op; } void swap(char *str1,char *str2) { char temp; temp=*str1; *str1=*str2; *str2=temp; } void permStr(char *str,int i) { // printf("%d\n",i); // cout<<strlen(str)<<endl; if(i==strlen(str)-1){ allSor[k][0]=str[0]; allSor[k][1]=str[1]; allSor[k][2]=str[2]; allSor[k][3]=str[3]; allSor[k][4]='\0'; k++; // printf("%s\n",str); // cout<<allSor[k]<<endl; } else { for(int j=i;j<strlen(str);j++) { // printf("i %d,j %d\n",i,j); swap(&str[i],&str[j]); permStr(str,i+1); swap(&str[i],&str[j]); } } }提交后看到别人的代码如下:
#include <iostream> #include <string> #include <algorithm> using namespace std; string poker[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; char C[12] = { '+', '+', '+', '-', '-', '-', '*', '*', '*', '/', '/', '/' }; int Calculate(int a, int b, char c) { switch (c){ case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; default: return -1; //不会有这个选项 } } int Caculate24(int a, int b, int c, int d, char C1, char C2, char C3) { return Calculate(Calculate(Calculate(a, b, C1), c, C2), d, C3); } bool Count24(int a, int b, int c, int d) { sort(C, C + 12); do { if (Caculate24(a, b, c, d, C[0], C[1], C[2]) == 24){ //do right; return true; } } while (next_permutation(C, C + 12)); return false; } int main() { string str[4]; cin >> str[0] >> str[1] >> str[2] >> str[3]; int i, j; bool legal; for (i = 0; i < 4; i++){ legal = false; for (j = 0; j < 13; j++){ if (str[i].compare(poker[j].c_str()) == 0) legal = true; } if (legal == false){ cout << "ERROR" << endl; return 0; } } int a, b, c, d; string *p; p = find(poker, poker + 13, str[0]); a = p - poker + 1; p = find(poker, poker + 13, str[1]); b = p - poker + 1; p = find(poker, poker + 13, str[2]); c = p - poker + 1; p = find(poker, poker + 13, str[3]); d = p - poker + 1; //现在a, b, c, d分别代表每一张牌的数值 int num[4]; num[0] = a, num[1] = b, num[2] = c, num[3] = d; do { if (Count24(num[0], num[1], num[2], num[3])){ cout << poker[num[0] - 1] << C[0] << poker[num[1] - 1] << C[1] << poker[num[2] - 1] << C[2] << poker[num[3] - 1] << endl; return 0; } } while (next_permutation(num, num+4)); cout << "NONE" << endl; return 0; }对比上述代码:第二种使用了许多STL中的函数。对标准库函数的掌握不遇到的问题:1,读入输入字符时没有设置结束标志位,导致后面调用全排列函数时返回的strlen(str)值为10(实际应为4)。
strlen的结果要在运行的时候才能计算出来,主要用来计算字符串的长度,不是类型占内存的大小,strlen只能用char*做参数,且必须是以''\0''结尾的。
2,cin的用法:cin空字符(包括回车,TAB,空格)都会当成一个输入的结束。连续的空字符会被忽略。
阅读第二种实现代码学到的知识:
1,使用STL的next_permutation函数生成全排列(C++)首先要先对要进行全排列的数据进行生序排列;因为该函数返回一个bool值,原来他是按照增序对参数的每一个值进行排列的,如果参数为完全降序的话,就认为到头了,会返回false。
http://www.slyar.com/blog/stl_next_permutation.html
http://blog.csdn.net/hongchangfirst/article/details/8663899
相关文章推荐
- 自组织特征映射神经网络(SOFM)
- SSH没有password安全日志
- 卷积神经网络 cnnff.m程序 中的前向传播算法 数据 分步解析
- NOIP2011-普及组复赛模拟试题-第二题-买票
- 洛谷 P1052 过河
- javascript中的innerHTML,innerText,outerHTML的用法及其区别
- OC - 知识点总结
- POJ 2524 Ubiquitous Religions
- 关于软件版本号的问题 软件版本号命名规则
- 今天无意中看到了str_split这个函数
- OC - Array,Dictionary,set,string方法总结
- spoj 1812 LCS2 - Longest Common Substring II (后缀自动机)
- 黑马程序员-Java高级:多线程
- 康威生命游戏的学习
- 华为机试 ——消消乐
- Codeforces Round #307 (Div. 2) A. GukiZ and Contest
- BZOJ2915 : [Poi1997] gen
- java简易登录工程mysql连接
- poj 1163 The Triangle
- Java MapReduce新旧API的比较