uva--10400+dfs+回溯

题意:

输入n个正整数和一个目标值,可以在这n个数中间填充+ - × /号进行运算,运算从左到右进行,不考虑运算符的优先性。 并且给定下面的规则:

1.填充符号时n个数的顺序不能改变。

2.填充除号的时候必须保证结果为整数。

3.每一步的结果必须在-32000~32000之间。

问是否可以求得目标值。

思路:

很显然可以用dfs+回溯来实现符号的填充,但是直接dfs是绝对会超时的(我就WA了一发);那么我们就要考虑剪枝了,这个题目可以利用状态来进行剪枝:我们记录下每一步得到的结果,如果回溯到这一步并且结果和原先的结果一致的话就可以直接返回。利用这个剪枝就可以AC啦。

还有就是每一步计算的结果都有可能为负数,为了利用数组进行判重,我们需要把结果加上50000后作为数组下标。

代码如下:

<span style="font-size:18px;">#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int a[110],n,flag,goal,vis[110][90000];
char ans[110];

inline int check(int a,int cur)
{
    if(a>=-32000&&a<=32000&&!vis[cur][a+50000])
    {
        vis[cur][a+50000]=1;
        return 1;
    }
    return 0;
}

void dfs(int cur,int sum)
{
     if(cur==n-1)
     {
         if(sum==goal)
         {
            ans[cur]='=';
            for(int i=0;i<n;i++)
                printf("%d%c",a[i],ans[i]);
            printf("%d\n",goal);
            flag=1;
         }
         return ;
     }
     if(flag)
        return ;
     if(check(sum+a[cur+1],cur))
     {
         ans[cur]='+';
         dfs(cur+1,sum+a[cur+1]);
     }
     if(flag)
        return ;
     if(check(sum-a[cur+1],cur))
     {
         ans[cur]='-';
         dfs(cur+1,sum-a[cur+1]);
     }
     if(flag)
        return ;
     if(check(sum*a[cur+1],cur))
     {
         ans[cur]='*';
         dfs(cur+1,sum*a[cur+1]);
     }
     if(flag)
        return ;
     if(sum%a[cur+1]==0&&check(sum/a[cur+1],cur))
     {
         ans[cur]='/';
         dfs(cur+1,sum/a[cur+1]);
     }
     if(flag)
        return ;
}

int main()
{
    int i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        scanf("%d",&goal);
        flag=0;
        dfs(0,a[0]);
        if(!flag)
           printf("NO EXPRESSION\n");
    }
 return 0;
}</span>
时间: 2024-10-19 04:21:50

uva--10400+dfs+回溯的相关文章

uva 11218 KTV(DFS+回溯)

uva 11218 KTV One song is extremely popular recently, so you and your friends decided to sing it in KTV. The song has 3 characters, so exactly 3 people should sing together each time (yes, there are 3 microphones in the room). There are exactly 9 peo

UVA 23 Out of 5(DFS+回溯)

Problem I 23 Out of 5 Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Your task is to write a program that can decide whether you can find an arithmetic expression consisting of five given numbers (1<=i<=5) tha

UVA How Big Is It? (DFS+回溯)

 How Big Is It?  Ian's going to California, and he has to pack his things, including his collection of circles. Given a set of circles, your program must find the smallest rectangular box in which they fit. All circles must touch the bottom of the bo

uva 10400 Game Show Math (填合适的运算符)

看到这种填合适的运算符之类的题目,第一感觉就是用dfs来枚举递归. 但邮箱道题目算法设计里面那么大的数据,想到有可能会超时. 用最直白的简单的方法dfs一遍后交上,超时. --需要判重和边界结束条件. 在所有能剪断的地方痛下狠手,狂加特判+return: 然后就炒鸡快了 #include<iostream> #include<cstring> #include<cstdio> #define ADD 32000 using namespace std; int arr[

poj1270Following Orders(拓扑排序+dfs回溯)

题目链接: 啊哈哈,点我点我 题意是: 第一列给出所有的字母数,第二列给出一些先后顺序.然后按字典序最小的方式输出所有的可能性... 思路: 总体来说是拓扑排序,但是又很多细节要考虑,首先要按字典序最小的方式输出,所以自然输入后要对这些字母进行排列,然后就是输入了,用scanf不能读空格,所以怎么建图呢??设置一个变量判断读入的先后顺序,那么建图完毕后,就拓扑排序了,那么多种方式自然就是dfs回溯了..那么这个问题就得到了解决.. 题目: Following Orders Time Limit:

CodeForces 550B Preparing Olympiad(DFS回溯)

[题目链接]:click here~~ [题目大意] 一组题目的数目(n<=15),每个题目有相应的难度,问你选择一定的题目(大于r个且小于l个)且选择后的题目里最小难度与最大难度差不小于x,求选择方案数. [解题思路]: DFS+回溯. 先发一发比较拙的代码: #include <bits/stdc++.h> using namespace std; const int N=1e5+10; int num[N],mum[N]; int n,m,q,t,l,r; int top,ans,

HDU4499 Cannon DFS 回溯的应用

题意就是给你一个n*m的棋盘,然后上面已经有了 棋子,并给出这些棋子的坐标,但是这些棋子是死的就是不能动,然后让你在棋盘上面摆炮,但是炮之间不能互相吃,吃的规则我们斗懂得 炮隔山打嘛,问你最多能放几个炮 肯定是搜索了,n,m最大才5,可能挺久没做了,对于回溯反而把握不好了,写了好久调试了好久,才过 #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #

POJ2488-A Knight&#39;s Journey(DFS+回溯)

题目链接:http://poj.org/problem?id=2488 A Knight's Journey Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 36695   Accepted: 12462 Description Background The knight is getting bored of seeing the same black and white squares again and again

蓝桥杯 算法提高 8皇后&#183;改 -- DFS 回溯

  算法提高 8皇后·改   时间限制:1.0s   内存限制:256.0MB 问题描述 规则同8皇后问题,但是棋盘上每格都有一个数字,要求八皇后所在格子数字之和最大. 输入格式 一个8*8的棋盘. 输出格式 所能得到的最大数字和 样例输入 1 2 3 4 5 6 7 89 10 11 12 13 14 15 1617 18 19 20 21 22 23 2425 26 27 28 29 30 31 3233 34 35 36 37 38 39 4041 42 43 44 45 46 47 48

poj1321——dfs回溯

POJ 1321  DFS回溯+递归枚举 棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24813   Accepted: 12261 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第一行