0
点赞
收藏
分享

微信扫一扫

shocked what dfs 可以这样用 带分数

三次方 2022-04-07 阅读 65

//枚举 a 枚举 c 最后用 c*n-a*c 求出 b  来检测 b 即可
//dfs_a(u,a) 用了u个数 a的值为a
//dfs_c(u,a,c) 用了u个数 a的值为a c的值为c
//c*n-a*c 求出b 然后将b每一位拿出来 看看是否用过 或者 是否有 0 全检测完 看看所有数是否用过
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10;
bool st[N],backup[N];
int n,ans=0;

bool check(int a,int c)//检查 a c 
{
    long long b=(long long)c*n-a*c;//通过a,c 将b求出来
    
    if(!a || !b || !c) return false;//有一个为0 就返回false
    
    memcpy(backup,st,sizeof st);//backup数组备份st 因为st有用 保存的是已选的数字 不能随意更改
    while(b)//将b每一位取出来
    {
        int k=b%10;
        b/=10;
        if(!k || backup[k]) return false;//b如果有一位是0 或者 有一位已经被选 返回false
        else backup[k]=true;
    }
    
    for(int i=1;i<=9;i++)//遍历每一个数 如果有没选的 就返回false
        if(!backup[i]) return false;
    
    return true;//都满足返回true
}

void dfs_c(int u,int a,int c)//枚举c
{
    if(u>=9) return;//选了9个数 说明b没有了
    if(check(a,c)) ans++;//检查a c是否满足
    
    for(int i=1;i<=9;i++)//枚举1~9 检查没有选的数
    {
        if(!st[i])
        {
            st[i]=true;//选
            dfs_c(u+1,a,c*10+i);//选了u+1个数 a不变 c的值c*10+i
            st[i]=false;//恢复现场
        }
    }
}

void dfs_a(int u,int a)//先来枚举 a
{
    if(a>=n) return;//a的值>=n 说明 b c就不存在了 回溯
    if(a) dfs_c(u,a,0);//a不为0 枚举c
    
    for(int i=1;i<=9;i++)//枚举1~9
    {
        if(!st[i])//如果没选
        {
            st[i]=true;//选中
            dfs_a(u+1,a*10+i);//选了u+1个数,a的值:a=a*10+i
            st[i]=false;//恢复现场
        }
    }
}

int main()
{
    scanf("%d",&n);
    
    dfs_a(0,0);//当前用了0个数字,当前a的值为0
    
    printf("%d\n",ans);
    return 0;
}
举报

相关推荐

0 条评论