蓝桥杯-带分数
链接:https://www.acwing.com/problem/content/1211/
备注:观看acwing视频课后总结,思路/总结有所借鉴
思路:\(num=a+\frac{b}{c}\),则我们可以枚举任意两个变量,为了防止精度损失,化简除法为乘法=》 \(b=c\times(num-a)\),而且a,c,num的范围为1e6,所以也要防止爆long long
经过分析,我们只需要枚举a和c,然后判断得到的b是否满足条件即可
总结:在设计递归的时候,很多算法博主和书籍都会强调递归搜索树,每次进行搜索时都是在画一棵树。
1.我们在设计递归的时候要考虑结束的标志,是遇到某个条件就剪枝return还是执行完函数直接结束
2.考虑我们在递归中传递的参数的含义,比如递归完成指数型枚举传递的参数代表的是枚举到的当前数值,而排列型枚举传递的参数表示的是当前已经选中的数值的个数。
本题中我们进行长度不同的排列型枚举,也就是在排列型枚举的搜索树的任意结点得到一个值,而不是在叶子结点得到长度为n的排列型枚举。
代码:
#include<bits/stdc++.h>
using namespace std;
int num;
int f[10];
int ans=0;
bool check(int a,int c){
    int b=1LL*c*(num-a);
    if(a*b*c<=0)return false;
    int atm[10];
    for(int i=1;i<=10;i++)atm[i]=f[i];
    while(b){
        int s=b%10;
        if(!s)return false;
        if(atm[s])return false;
        atm[s]=1;
        b/=10;
    }
    for(int i=1;i<=9;i++)
    if(!atm[i])return false;
    return true;
}
void dfs_c(int x,int a,int c){
    if(!a)return ;
    if(x>=9)return;
    if(check(a,c))ans++;
    for(int i=1;i<=9;i++){
        if(!f[i]){
            f[i]=1;
            dfs_c(x+1,a,c*10+i);
            f[i]=0;
        }
    }
    
}
void  dfs_a(int x,int a){
    if(x>6)return ;
    dfs_c(0,a,0);
    for(int i=1;i<=9;i++){
        if(!f[i]){
            f[i]=1;
            dfs_a(x+1,a*10+i);
            f[i]=0;
        }        
    }
}
int main (){
    cin>>num;
    dfs_a(0,0);
    cout<<ans;
    return 0;
}

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号