------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
今天又遇到了一个比较难的题目,网上查了半天写的都比较乱。因为我零基础,代码相当不规范,希望多多见谅。不多说,下面我贴上代码给其他零基础的有个参考。
题目说明
计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(*), 除(/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王:
3 4 5 6 7 8 9 10 J Q K A 2joker 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”表示无解。
输入 输出
A A A A NONE
3 2 4 joker ERROR
3 J 3 K 3/3*J+K
<span style="font-size:14px;">代码:
//
// main.c
// 24pointGame
//
// Created by Bo on 15-2-10.
// Copyright (c) 2015年 Bo All rights reserved.
//
#include
#include
#include
int isDone;
double cards[4]; //存储输入的四张牌
int flag[4]; //dfs时标记哪些牌用过
double number(char card[]) //把字符串转成double类型
{
if(strcmp(card, "A")==0)
return 1;
else if(strcmp(card, "J")==0)
return 11;
else if(strcmp(card, "Q")==0)
return 12;
else if(strcmp(card, "K")==0)
return 13;
else if(strcmp(card, "joker")==0)
return 0;
else if(strcmp(card, "JOKER")==0)
return 0;
else
return atof(card);
}
char* str(double card) //把double类型转成字符串
{
if(card == 1)
return "A";
else if(card == 11)
return "J";
else if(card == 12)
return "Q";
else if(card == 13)
return "K";
else if(card == 2) return "2";
else if(card == 3) return "3";
else if(card == 4) return "4";
else if(card == 5) return "5";
else if(card == 6) return "6";
else if(card == 7) return "7";
else if(card == 8) return "8";
else if(card == 9) return "9";
else if(card == 10) return "10";
return "";
}
int check(double cards[]) //检查是否存在大小王
{
for(int i = 0;i < 4;i ++)
{
if(cards[i]==0)
return 0;
}
return 1;
}
void dfs(double path1[],char path2[],double count,int num)
{
if(isDone) return ;
if(count == 24&&num == 4) //总数等于24并且用了4张牌,证明找到
{
// printf("%s\n",path);
for(int index = 0;index<3;index ++)
{
printf("%s%c",str(path1[index]),path2[index+1]);
printf("%s\n",str(path1[3]));
isDone = 1; //作为一个标记是否已找到可以构成24点的
return;
}
for(int i = 0; i < 4 ; i++)
{
if(!flag[i])
{
flag[i]=1; //标记这张牌用了
path1[num] = cards[i];
path2[num] = '+';
dfs(path1, path2, count + cards[i], num+1); //dfs加上cards[i]的情况
if(num > 0)
{
path2[num] = '-';
dfs(path1, path2, count - cards[i], num+1); //dfs减去cards[i]的情况
path2[num] = '*';
dfs(path1, path2, count * cards[i], num+1); //dfs乘以cards[i]的情况
path2[num] = '/';
dfs(path1, path2, count / cards[i], num+1); //dfs除以cards[i]的情况
}
flag[i]=0; //取消标记,表示放掉这张牌
}
if(isDone)
return ;
}
}
int main(int argc, const char * argv[])
{
// insert code here...
double count,path1[4]; //path1数组用来存储输出的数字
int num; //用了多少张扑克牌
char path2[4]; //path2数组用来存储输出的加减乘除字符
char firstCard[5],secondCard[5],thirdCard[5],fourthCard[5];
while(scanf("%s%s%s%s",firstCard,secondCard,thirdCard,fourthCard)!=EOF)
{
count = isDone = num =0;
cards[0] = number(firstCard);
cards[1] = number(secondCard);
cards[2] = number(thirdCard);
cards[3] = number(fourthCard);
if(!check(cards))
{
printf("ERROR\n");
continue;
}
dfs(path1,path2,count,num);
if(isDone == 0) //如果等于0,证明没有标记过,则找不到
printf("NONE\n");
}
return 0;
}
java code:
import java.util.Scanner;
public class Main {
static boolean isDone;
static int[] cards = new int[4];//存储输入的四张牌
static boolean[] flag = new boolean[4];//dfs时标记哪些牌用过
static int number(String card) //把字符串转成double类型
{
if(card.equals("A"))
return 1;
else if(card.equals("J"))
return 11;
else if(card.equals("Q"))
return 12;
else if(card.equals("K"))
return 13;
else if(card.equals("joker"))
return 0;
else if(card.equals("JOKER"))
return 0;
else
return Integer.parseInt(card);
}
static String str(double card) //把double类型转成字符串
{
if(card == 1)
return "A";
else if(card == 11)
return "J";
else if(card == 12)
return "Q";
else if(card == 13)
return "K";
else if(card == 2) return "2";
else if(card == 3) return "3";
else if(card == 4) return "4";
else if(card == 5) return "5";
else if(card == 6) return "6";
else if(card == 7) return "7";
else if(card == 8) return "8";
else if(card == 9) return "9";
else if(card == 10) return "10";
return "";
}
static boolean check(int cards[]) //检查是否存在大小王
{
for(int i = 0;i < 4;i ++)
{
if(cards[i]==0)
return false;
}
return true;
}
static void dfs(int path1[],String path2[],double count,int num)
{
if(isDone) return ;
if(count == 24 && num == 4) //总数等于24并且用了4张牌,证明找到
{
for(int index = 0;index<3;index ++)
{
System.out.print(str(path1[index])+path2[index+1]);
}
System.out.println(str(path1[3]));
isDone = true; //作为一个标记是否已找到可以构成24点的
return;
}
for(int i = 0; i < 4 ; i++)
{
if(!flag[i])
{
flag[i]=true; //标记这张牌用了
path1[num] = cards[i];
path2[num] = "+";
dfs(path1, path2, count + cards[i], num+1); //dfs加上cards[i]的情况
if(num > 0)
{
path2[num] = "-";
dfs(path1, path2, count - cards[i], num+1); //dfs减去cards[i]的情况
path2[num] = "*";
dfs(path1, path2, count * cards[i], num+1); //dfs乘以cards[i]的情况
path2[num] = "/";
dfs(path1, path2, count / cards[i], num+1); //dfs除以cards[i]的情况
}
flag[i]=false; //取消标记,表示放掉这张牌
}
if(isDone)
return ;
}
}
public static void main(String[] args) {
double count;
int[] path1 = new int[4];
int num;
String[] path2 = new String[4];
String firstCard,secondCard,thirdCard,fourthCard;
Scanner cin = new Scanner(System.in);
while (cin.hasNext()) {
firstCard = cin.next();
secondCard = cin.next();
thirdCard = cin.next();
fourthCard = cin.next();
count = 0.0;
num = 0;
isDone = false;
cards[0] = number(firstCard);
cards[1] = number(secondCard);
cards[2] = number(thirdCard);
cards[3] = number(fourthCard);
if(!check(cards))
{
System.out.println("ERROR");
continue;
}
dfs(path1,path2,count,num);
if(!isDone) //如果等于false,证明没有标记过,则找不到
System.out.println("NONE");
}
}
}</span>