蓝桥杯-带分数
链接: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号