UVa 10400 - Game Show Math

来源:互联网 发布:fanuc铣床编程实例 编辑:程序博客网 时间:2024/05/18 03:07

DFS+剪枝。因为题目中要求每一步运算的范围都不会超过-32000~32000这个区间,因此可以将每一步运算的状态存在一个vis数组里,只要重复则不必要再往下计算,这样就可以将3的99次方的运算量降为99*4*64000。

代码如下:

#include <iostream>#include <algorithm>#include <cstring>#include <cstdlib>#include <cstdio>#include <cmath>using namespace std;bool vis[100][64001];int num, save[101], flag;char expo[100];void dfs(int cur, int sum){    if(cur == num)    {        if(sum == save[num])            flag = 1;        return ;    }    int ans = sum + save[cur];    expo[cur - 1] = '+';    if(ans <= 32000 &&       ans >= -32000 && // 判断是否超出范围      !vis[cur][ans + 32000]      )    {        vis[cur][ans + 32000] = true;        dfs(cur + 1, ans);        if(flag)            return ;    }    ans = sum - save[cur];    expo[cur - 1] = '-';    if(ans >= -32000 &&       ans <= 32000 &&      !vis[cur][ans + 32000]      )    {        vis[cur][ans + 32000] = true;        dfs(cur + 1, ans);        if(flag)            return ;    }    ans = sum * save[cur];    expo[cur - 1] = '*';    if(ans <= 32000 &&       ans >= -32000 &&      !vis[cur][ans + 32000]      )    {        vis[cur][ans + 32000] = true;        dfs(cur + 1, ans);        if(flag)            return ;    }    ans = sum / save[cur];    expo[cur - 1] = '/';    if(!vis[cur][ans + 32000])    {        vis[cur][ans + 32000] = true;        dfs(cur + 1, ans);        if(flag)            return ;    }}int main(){#ifdef test    freopen("sample.txt", "r", stdin);#endif    int n;    scanf("%d", &n);    while(n--)    {        flag = 0;        scanf("%d", &num);        memset(vis, false, sizeof(vis));        for(int i = 0; i <= num; i++)            scanf("%d", &save[i]);        dfs(1, save[0]);        if(flag)        {            expo[num - 1] = '=';            for(int i = 0; i < num; i++)                printf("%d%c", save[i], expo[i]);            printf("%d\n", save[num]);        }        else            printf("NO EXPRESSION\n");    }    return 0;}


原创粉丝点击