欢迎评论指出错误,提出疑问,或者不介意给出更好的解法,有交流才有进步。
PREV-3(带分数)
这道题就简单的求1-9九个数组成的带分数来表示数值n的个数
枚举1-9九个数组成的全排列,然后把每种排列分成整数、分子、分母三段
然后简单判断以下每个带分数是否和n相等
这里的剪枝在于枚举整数、分子、分母分别的位数
分母的位数肯定小于等于分子的位数
整数的位数肯定小于等于n的位数
<C++> Code
1 #include<stdio.h> 2 3 int n,a[10],ans,len; 4 bool f[10];//标记是否已加入排列中 5 6 //计算a[]中从第s位起长l位的整数大小 7 int getNum(int s,int l){ 8 int num = 0; 9 for(int i = 0 ; i < l ; i++){ 10 num = num * 10 + a[s+i]; 11 } 12 return num; 13 } 14 15 //判断全排列中是否有组成满足条件的带分数 16 void JudgeNum(){ 17 //现在枚举带分数 整数、分母、分子的位数 18 for(int zs = 1 ; zs <= len ; zs++){//整数的位数 19 int NumZS = getNum(0 , zs);//整数 20 int Len = 9 - zs;//分子加分母的位数 21 for(int fm = 1 ; fm <= Len/2 ; fm++){ 22 int NumFM = getNum(zs , fm);//分母 23 int fz = Len - fm; 24 int NumFZ = getNum(zs + fm , fz);//分子 25 if(NumFZ%NumFM == 0 && (NumZS + NumFZ/NumFM) == n) 26 ans++; 27 } 28 } 29 } 30 31 32 //dfs遍历1-9组成的全排列 33 void dfs(int k){ 34 if(k == 9){//生成了一种排列 35 JudgeNum(); 36 return; 37 } 38 for(int i = 1 ; i < 10 ; i++){//枚举第k位上的数 39 if(!f[i]){ 40 a[k] = i; 41 f[i] = true; 42 dfs(k+1); 43 f[i] = false; 44 } 45 } 46 } 47 48 49 void work(){ 50 //因为全局变量自动初始化为0(false),所以省了初始化 51 int x = n; 52 while(x){//求n的位数len 53 len++; 54 x /= 10; 55 } 56 dfs(0); 57 printf("%d\n",ans); 58 } 59 60 61 int main() 62 { 63 scanf("%d",&n); 64 work(); 65 return 0; 66 }