zoukankan      html  css  js  c++  java
  • Gym 100989L (DFS)

    AbdelKader enjoys math. He feels very frustrated whenever he sees an incorrect equation and so he tries to make it correct as quickly as possible!

    Given an equation of the form: A1 o A2 o A3 o ... o An  =  0, where o is either + or -. Your task is to help AbdelKader find the minimum number of changes to the operators + and -, such that the equation becomes correct.

    You are allowed to replace any number of pluses with minuses, and any number of minuses with pluses.

    Input

    The first line of input contains an integer N (2 ≤ N ≤ 20), the number of terms in the equation.

    The second line contains N integers separated by a plus + or a minus -, each value is between 1 and 108.

    Values and operators are separated by a single space.

    Output

    If it is impossible to make the equation correct by replacing operators, print  - 1, otherwise print the minimum number of needed changes.

    题意:给出了你一个数字n,和一个由n个数字以及n-1个加减运算符组成的算式,你可以把 ‘+’ 变成 ‘-’,或者把‘-’变成加‘+’。问你最少改变几个符号可以使算式等于0。注意:符号和数字之间用空格隔开。

    思路:这道题可以用DFS来解决,枚举所有符号的改变情况,每个符号只有两种情况,改变或者不变。递归每个符号的两种情况,DFS(不变),DFS(改变),记录递归的层数,当递归到最后一个符号时判断运算结果是否符合要求,记录符合要求的最小改变次数。具体步骤看代码中的标注。

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<string>
     6 #include<algorithm>
     7 #include<stack>
     8 #include<queue>
     9 #define ll long long
    10 #define inf 0x3f3f3f3f
    11 using namespace std;
    12 
    13 int minn;
    14 int n,num[30],num1,num2;
    15 char str[30];
    16 
    17 int compute() //计算结果是否为0 
    18 {
    19     int it=0,ans = num[0];
    20     while(it < num2)
    21     {
    22         if(str[it] == '+')
    23             ans += num[it+1];
    24         else
    25             ans -= num[it+1];
    26         it++;
    27     }
    28     if(ans == 0) return 1;
    29     else return 0;
    30 }
    31 
    32 void dfs(int times,int change) //times表示判断第几个符号,change表示改变了多少次 
    33 {
    34     if(times >= num2) //如果已经判断完所有的符号了,就计算结果 
    35     {
    36         if(change < minn && compute()) //如果改变的次数比之前记录的小且计算结果符合要求 
    37         {
    38             minn = change; //就重新记录最小值 
    39         }
    40         return;
    41     }
    42     
    43     dfs(times+1,change); //递归不改变这个符号的额情况
    44      
    45     if(str[times] == '+') //改变符号 
    46         str[times] = '-';
    47     else str[times] = '+';
    48     dfs(times+1,change+1); //递归改变符号的情况,改变数加1 
    49     if(str[times] == '+') //回溯,将改变的的符号还原 
    50     str[times] = '-';
    51     else str[times] = '+';
    52     return;
    53 }
    54 
    55 int main()
    56 {
    57     while(cin>>n)
    58     {
    59         num1=0,num2=0;
    60         minn = inf;
    61         
    62         for(int i=1; i<=n*2-1; ++i) //注意输入方式,输入一个数字,一个运算符,总共2*n-1个,数字和字母之间有空格 
    63         {
    64             if(i%2==1) // 如果是奇数位置,则输入数字 
    65             {
    66                 scanf("%d",&num[num1++]);
    67                 getchar();//吸收空格 
    68             }
    69             else scanf("%c",&str[num2++]);//输入运算符 
    70         }
    71         dfs(0,0);
    72         if(minn == inf)
    73             cout<<"-1"<<endl;
    74         else
    75             cout<<minn<<endl;
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    找出一个序列中第k大的元素 [快速选择问题]
    选择排序算法分析
    冒泡排序算法分析
    mysql的安装和配置
    Redis 简明教程
    flink-杂记
    redis-list
    bean创建过程
    镜像
    docker-命令
  • 原文地址:https://www.cnblogs.com/tuyang1129/p/9272589.html
Copyright © 2011-2022 走看看