hdu 1427 速算24点

速算24点

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3226 Accepted Submission(s): 775


Problem Description
速算24点相信绝大多数人都玩过。就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13)。要求只用'+','-','*','/'运算符以及括号改变运算顺序,使得最终运算结果为24(每个数必须且仅能用一次)。游戏很简单,但遇到无解的情况往往让人很郁闷。你的任务就是针对每一组随机产生的四张牌,判断是否有解。我们另外规定,整个计算过程中都不能出现小数。

Input
每组输入数据占一行,给定四张牌。

Output
每一组输入数据对应一行输出。如果有解则输出"Yes",无解则输出"No"。

Sample Input
   
   
   
   
A 2 3 6 3 3 8 8

Sample Output
   
   
   
   
Yes No

算法分析:

首先进行全排列,之后进行深搜,注意括号只有两种情况(a@b)@(c@d)和((a@b)@c)@d.

#include<iostream>
#include<algorithm>
using namespace std;
int res[4];
void dfs(int sum, int cur, int temp);
bool flag = 0;
int main()
{
    char s[3];
    int i,j,k;
    while(1)
    {
        for(i = 0;i < 4;i ++)
        {
            if(scanf("%s",s) == EOF) return 0;
            if(s[0] == 'A') res[i] = 1;
            else if(s[0] == 'J') res[i] = 11;
            else if(s[0] == 'Q') res[i] = 12;
            else if(s[0] == 'K') res[i] = 13;
            else if(s[0] == '1' && s[1] == '0') res[i] = 10;
            else res[i] = s[0] - '0';
        }
        sort(res, res+4);
        flag = 0;
        do
        {
            dfs(res[0], 1, res[1]);
        }while(next_permutation(res, res+4)&&!flag);
        if(flag) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
void dfs(int sum, int cur, int temp)
{
    if(flag)
        return;
    if(cur==3)
    {
        if(sum+temp==24)
            flag=1;
        if(sum-temp==24)
            flag=1;
        if(sum*temp==24)
            flag=1;
        if(temp!=0&&sum%temp==0&&sum/temp==24)
            flag=1;
        return;
    }
    dfs(sum+temp, cur+1, res[cur+1]);
    dfs(sum-temp, cur+1, res[cur+1]);
    dfs(sum*temp, cur+1, res[cur+1]);
    if(temp!=0&&sum%temp==0)
        dfs(sum/temp, cur+1, res[cur+1]);
    dfs(sum, cur+1, temp+res[cur+1]);
    dfs(sum, cur+1, temp-res[cur+1]);
    dfs(sum, cur+1, temp*res[cur+1]);
    if(res[cur+1]!=0&&temp%res[cur+1]==0)
        dfs(sum, cur+1, temp/res[cur+1]);
}
另一种解法,
#include <stdio.h>
#include <string.h>
int a[10];
int map[10];
int flag = 1;
int get(char *str)
{
	if(str[0] == 'A')
		return 1;
	if(str[0] == '1')
		return 10;
	if(str[0] == 'J')
		return 11;
	if(str[0] == 'Q')
		return 12;
	if(str[0] == 'K')
		return 13;
	return str[0] - '0';
}

void DFS(int s1,int s2,int k,int x)//(A@B)@(C@D) 
{
	int i;
	if(k == 4)
	{
		if(x == 1)
		{
			if(s1 == 24 || s1 == -24)
			{
				flag = 1;
			}
		}
		else
		{
			if(s1 + s2 == 24 || s1 + s2 == -24 || s1 - s2 == 24 || s1 - s2 == -24 || s1 * s2 == 24 || s1 * s2 == -24)
				flag = 1;
			if(s2 && s1 % s2 == 0 && s1 /s2 == 24)
			{
				flag = 1;
			}
		}
			return ;
	}
	for(i = 1;i <= 4; i++)
	{
		if(!map[i])
		{
			map[i] = 1;
			if(k == 0)
			{
				DFS(a[i],s2,k+1,1);
			}
			else if(k == 1)
			{
				DFS(s1+a[i],s2,k+1,1);
				DFS(s1-a[i],s2,k+1,1);
				DFS(s1*a[i],s2,k+1,1);
				if(a[i] && s1 % a[i] == 0)
				DFS(s1/a[i],s2,k+1,1);
			}
			else
			{
				if(k == 2)
				{
					
						DFS(s1+a[i],s2,k+1,1);
						DFS(s1-a[i],s2,k+1,1);
						DFS(s1*a[i],s2,k+1,1);
						if(a[i] && s1 % a[i] == 0)
						DFS(s1/a[i],s2,k+1,1);
		
						DFS(s1,a[i],k+1,2);
				}
				else
				{
					if(x == 1)
					{
						DFS(s1+a[i],s2,k+1,1);
						DFS(s1-a[i],s2,k+1,1);
						DFS(s1*a[i],s2,k+1,1);
						if(a[i] && s1 % a[i] == 0)
						DFS(s1/a[i],s2,k+1,1);
					}
					else
					{
						DFS(s1,s2+a[i],k+1,2);
						DFS(s1,s2-a[i],k+1,2);
						DFS(s1,s2*a[i],k+1,2);
						if(a[i] && s2 % a[i] == 0)
						DFS(s1,s2 / a[i],k+1,2);
					}
				}
			}
			map[i] = 0;	
						
		}
	}
}

int main()
{
	char str[12];
	int i;
	while(scanf("%s",str)!=EOF)
	{
		
		flag = 0;
		a[1] = get(str);
		for(i = 2;i <= 4;i++)
		{
			scanf("%s",str);
			a[i] = get(str);
		}
		memset(map,0,sizeof(map));
		DFS(0,0,0,1);
		if(flag)
			printf("Yes\n");
		else
			printf("No\n");
	}
	return 0;
}

关于next_permutation函数在C++(迭代访问)与C(下标访问)中的用法的使用,函数类型返回值是bool类型。

C++:

#include <iostream>
#include <algorithm>
#include <string>
 
using namespace std;
 
int main()
{
    string str;
    cin >> str;
    sort(str.begin(), str.end());
    cout << str << endl;
    while (next_permutation(str.begin(), str.end()))
    {
        cout << str << endl;
    }
    return 0;
}
C:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 100
 
using namespace std;
 
int main()
{
    int length;
    char str[MAX];
    gets(str);
    length = strlen(str);
    sort(str, str + length);
    puts(str);
    while (next_permutation(str, str + length))
    {
        puts(str);
    }
    return 0;
}


你可能感兴趣的:(速算,DFS)