华为OJ题目:24点运算
来源:互联网 发布:淘宝店铺怎么设置打折 编辑:程序博客网 时间:2024/05/26 02:20
计算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的结果为24
6.如果存在多种算式都能计算得出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
0 0
- 华为OJ题目:24点运算
- 【华为OJ】【107-24点运算】
- [华为OJ--C++]107-24点运算
- 华为oj中级 24点运算
- 华为OJ——24点运算
- 华为oj 24点游戏
- 华为OJ一个题目
- 华为OJ(24点游戏)
- 华为oj 24点游戏算法
- 【华为OJ】【097-24点游戏算法】
- 华为OJ 初级:24点游戏算法
- 24点游戏算法-华为OJ
- 华为OJ:24点游戏算法
- 华为oj初级 24点游戏算法
- 华为OJ平台练习题--24点游戏
- 华为OJ24点运算
- 华为OJ题目 配置文件恢复
- 华为OJ(扑克牌之24点游戏)
- hdu 1250 高精度+斐波那契
- centos7下安装adagios
- 谷歌技术"三宝"之谷歌文件系统
- ThreadLocal用法和实现原理
- Google后Hadoop时代的新“三驾马车”
- 华为OJ题目:24点运算
- 配置python环境
- UIAlertController用法大全
- nc命令
- 跨浏览器添加事件处理程序
- 杭电 2094 产生冠军(拓扑排序)
- JavaScript高级程序设计 第二章 --- 在HTML中使用JavaScript
- 【Ajax技术】使用XHR对象发送和接受数据
- LeetCode: Implement pow(x, n).