2星难度-寒假作业

题目:
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □
每个方块代表1~13中的某一个数字,但不能重复。
比如:
6 + 7 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
以及:
7 + 6 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

思路:这题很容易看出来是DFS  深度搜索,遍历每一种情况,并判断 是否符合题目要求,递归结束当12个格子填满

这题其实不算难,但是DFS要比较熟,这题自己卡了一下子,找了挺久的Bug  知道自己是多算了很多情况吗,但是愣是没找到错在哪,不过最终还是被找出来了,

想想,如果是现场赛的时候花这么多时间找Bug就完蛋了,说明自己对DFS还是不熟,多做多做!!!

下面看代码:

#include<iostream>
#include<string.h>
using namespace std;
const int maxn=15+5;
bool vis[maxn];
int a[maxn];
int ans=0;
void dfs1(int sum,int pre,int now)//分别代表现在是第几个点 第一个框和第二个框的值分别是多少
{
    if(sum==12)//12个格子填满  递归结束
    {
        ans++;
        for(int i=1;i<=12;i++) cout<<a[i]<<" ";
        cout<<endl;
        //cout<<ans<<endl;
        return ;
    }
    if(pre!=0&&now!=0)//两个格子都填满了 代表第三个格子已经确定了  
    {
        if(sum==2)//这里我默认的顺序是+ - * /
        {
            int z=pre+now;
            if(z<=13&&z>=1&&(!vis[z]))
            {
                vis[z]=true;
                a[1]=pre;
                a[2]=now;
                a[3]=z;
                //cout<<pre<<"+"<<now<<"="<<z<<endl;
                dfs1(sum+1,0,0);
                vis[z]=false;
            }
            else return ;
        }
        else if(sum==5)
        {
            int z=pre-now;
            if(z<=13&&z>=1&&(!vis[z]))
            {
                vis[z]=true;
                a[4]=pre;
                a[5]=now;
                a[6]=z;
                //cout<<pre<<"-"<<now<<"="<<z<<endl;
                dfs1(sum+1,0,0);
                vis[z]=false;
            }
            else return ;
        }
        else if(sum==8)
        {
            int z=pre*now;
            if(z<=13&&z>=1&&(!vis[z]))
            {
                vis[z]=true;
                a[7]=pre;
                a[8]=now;
                a[9]=z;
                //cout<<pre<<"*"<<now<<"="<<z<<endl;
                dfs1(sum+1,0,0);
                vis[z]=false;
            }
            else return ;
        }
        else if(sum==11)
        {
            if(pre%now==0)
            {
                int z=pre/now;
                if(z<=13&&z>=1&&(!vis[z]))
                {
                    vis[z]=true;
                    a[10]=pre;
                    a[11]=now;
                    a[12]=z;
                    //cout<<pre<<"/"<<now<<"="<<z<<endl;
                    dfs1(sum+1,0,0);
                    vis[z]=false;
                }
                else return ;
            }
            else return ;
        }
        return ;
    }
    for(int i=1;i<=13;i++)//遍历每一个值
    {
        if(!vis[i])
        {
            vis[i]=true;
            if(pre==0) dfs1(sum+1,i,now);
            else if(now==0) dfs1(sum+1,pre,i);// !!!!我就是这里错了   写了两个if  改为else if就对了
            /*  
            因为两个if的话 
            比如前面格子取4  递归下去后面格子取5  那么就是(4,5) 
            同时执行下面的if  后面的格子取4 前面的格子取5  那么就是(5,4)
            
            前面格子取5  递归下去后面格子取4  那么就是(5,4)
            同时执行下面的if  后面的格子取5 递归下去前面格子取4 那么就是(4,5)
            是不是重复了  
            */
            vis[i]=false;
        }
    }

}
int main()
{
    memset(vis,false,sizeof(vis));
    dfs1(0,0,0);
    cout<<ans<<endl;
    return 0;
}
当初的梦想实现了吗,事到如今只好放弃吗~
原文地址:https://www.cnblogs.com/caijiaming/p/10333794.html