3星难度-算式填符号

题目:
匪警请拨110,即使手机欠费也可拨通!
为了保障社会秩序,保护人民群众生命财产安全,警察叔叔需要与罪犯斗智斗勇,因而需要经常性地进行体力训练和智力训练!
某批警察叔叔正在进行智力训练:
1 2 3 4 5 6 7 8 9 = 110
请看上边的算式,为了使等式成立,需要在数字间填入加号或者减号(可以不填,但不能填入其它符号)。之间没有填入符号的数字组合成一个数,例如:12+34+56+7-8+9 就是一种合格的填法;123+4+5+67-89 是另一个可能的答案。

请你利用计算机的优势,帮助警察叔叔快速找到所有答案。
每个答案占一行。形如:
12+34+56+7-8+9
123+4+5+67-89

答案是10

这题到最后的确做出来了,但是花时间也太长了,一个多小时吧   打比赛的时候可不能可这样,感觉对dfs还是不够熟悉  慢慢积累吧!

思路:  其实就是dfs每两个数之间的符号,都有三种情况,+ - 另外一个可以用一个*来表示。  中间的都一样的 但是边界处理要注意!!!

首先是第一个数  同样的 + - *三种操作都不能少  总共需要填八个空 所以当知道是第八个空时  第九个空只需要填一次  不然就多算了两次了 。

中间一些细节真的要注意!  特别是当是-的时候 后面一直是*  这种情情况也要考虑到!!  

下面看代码:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
const int maxn=1000;
int a[maxn];
char s[maxn];
int an=0;
void solve(int cnt,int ans,int sum,char c,bool limit)//cnt表示第几位 ans表示到目前为止总和 sum表示当前遍历的这个数是多少 c表示这个空填什么  limit -还是+
{
    s[cnt]=c;
    if(cnt==9)
    {
        if(limit) ans-=sum;//注意把最后一个数加上去
        else ans+=sum;
        if(ans==110)
        {
            //for(int i=1;i<10;i++) cout<<s[i];
            //cout<<endl;
            for(int i=1;i<10;i++)
            {
                printf("%d",a[i]);
                if(s[i]!='*'&&(i<9)) printf("%c",s[i]);
            }
            cout<<endl;
            an++;

        }
        return ;
    }
    if(c=='+')//这个空是+  代表前面就已经和后面的断了  
    {
        if(limit)
        {
            if(cnt!=8)
            {
                solve(cnt+1,ans-sum,a[cnt+1],'*',false);
                solve(cnt+1,ans-sum,a[cnt+1],'-',false);
                solve(cnt+1,ans-sum,a[cnt+1],'+',false);
            }
            else solve(cnt+1,ans-sum,a[cnt+1],'*',false);
        }

        else
        {
            if(cnt!=8)
            {
                solve(cnt+1,ans+sum,a[cnt+1],'*',false);
                solve(cnt+1,ans+sum,a[cnt+1],'-',false);
                solve(cnt+1,ans+sum,a[cnt+1],'+',false);
            }
            else solve(cnt+1,ans+sum,a[cnt+1],'*',false);
        }
        //sum+=a[cnt];
    }
    if(c=='-')
    {
        //a[cnt+1]=-a[cnt+1];
        if(limit)
        {
            if(cnt!=8)
            {
                solve(cnt+1,ans-sum,a[cnt+1],'*',true);
                solve(cnt+1,ans-sum,a[cnt+1],'-',true);
                solve(cnt+1,ans-sum,a[cnt+1],'+',true);
            }
            else solve(cnt+1,ans-sum,a[cnt+1],'*',true);
        }
        else
        {
            if(cnt!=8)
            {
                solve(cnt+1,ans+sum,a[cnt+1],'*',true);
                solve(cnt+1,ans+sum,a[cnt+1],'-',true);
                solve(cnt+1,ans+sum,a[cnt+1],'+',true);
            }
            else solve(cnt+1,ans+sum,a[cnt+1],'*',true);
        }
    }
    if(c=='*')//这个箜是*  代表前面的和后面的还没有断 
    {
        if(cnt!=8)
        {
            solve(cnt+1,ans,sum*10+a[cnt+1],'+',limit);
            solve(cnt+1,ans,sum*10+a[cnt+1],'-',limit);
            solve(cnt+1,ans,sum*10+a[cnt+1],'*',limit);
        }
        else solve(cnt+1,ans,sum*10+a[cnt+1],'+',limit);
    }

}
int main()
{
    //第一个空三种情况
    for(int i=1;i<10;i++) a[i]=i;
    solve(1,0,1,'*',false);
    for(int i=1;i<10;i++) a[i]=i;
    solve(1,0,1,'-',false);
    for(int i=1;i<10;i++) a[i]=i;
    solve(1,0,1,'+',false);
    cout<<an<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/caijiaming/p/10351719.html