c语言蓝桥杯的一道题 我百度了答案但是看不太懂,希望有人帮忙解释一下,只要注释一下dfs函数就好了!!

形如:1/a 的分数称为单位分数。

可以把1分解为若干个互不相同的单位分数之和。
例如:
1 = 1/2 + 1/3 + 1/9 + 1/18
1 = 1/2 + 1/3 + 1/10 + 1/15
1 = 1/3 + 1/5 + 1/7 + 1/9 + 1/11 + 1/15 + 1/35 + 1/45 + 1/231
等等,类似这样的分解无穷无尽。

我们增加一个约束条件:最大的分母必须不超过30

请你求出分解为n项时的所有不同分解法。

数据格式要求:

输入一个整数n,表示要分解为n项(n<12)
输出分解后的单位分数项,中间用一个空格分开。
每种分解法占用一行,行间的顺序按照分母从小到大排序。

代码如下
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 100

using namespace std;
long long a[MAXN+8],ans[MAXN+8],n;
bool find_ans;
long long gcd(long long a,long long b)
{
long long t;
while(b)
{
t=a%b;
a=b;
b=t;
}
return a;
}
bool better()
{
int i;
for(i=n;i>=0;i--)
{
if(a[i]==ans[i])
continue;
return (ans[i]==0||a[i]<ans[i]);
}
return 0;
}
void dfs(int cur,int s,long long fz,long long fm)
{
if(cur==n)
{
if(fm%fz)
return ;
a[cur]=fm/fz;/*
if(better())
memcpy(ans,a,sizeof(long long)*(n+1));*/
if(a[n]>=30)
return ;
for(int i=0;i<n;i++)
printf("1/%d ",(int)a[i]);
printf("1/%d\n",(int)a[n]);
return ;
}
s=(int)max(s*1LL,fm/fz+1);
int i;
long long A,B,Gcd;
for(i=s;;i++)
{
if((i*fz)>=(fm*(n-cur+1)))
break;
a[cur]=i;
B=fm*i;
A=fz*i-fm;
Gcd=gcd(A,B);
dfs(cur+1,i+1,A/Gcd,B/Gcd);
}
return ;
}
int main()
{
long long a,b;
//cin>>a>>b;
a=1,b=1;
cin>>n;
n--;
dfs(0,b/a+1,a,b);
return 0;
}

void dfs(int cur,        // 当前需要查找的分式
    int s,               // 分母的最小值
    long long fz,        // 剩余未分配部分大小的分子
    long long fm)        // 剩余未分配部分大小的分母
{
    // 如果需要查找最后一个分式
    if (cur == n)
    {
        // 如果分母不能被分子整除,则最后一个分式无法构成
        if (fm % fz)
            return;        // 从搜索中退回

        // 最后一个分式的分母
        a[cur] = fm / fz;

        // 如果最后一个分式的分母大于30,从搜索中返回
        if (a[n] > 30)
            return;        // 从搜索中退回

        // 把所有的分式打印出来
        for (int i = 0; i < n; i++)
            printf("1/%d ", (int)a[i]);
        printf("1/%d\n", (int)a[n]);
        return;        // 从搜索中退回
    }

    // 计算下一个分母的最小值
    s = (int)max(s * 1LL, fm / fz + 1);

    int i;
    long long A, B, Gcd;

    // 枚举所有可能的下一个分母
    for (i = s;; i++)
    {
        // 假设后面所有的分式全部的分母都是 i,也不能够使得总和达到 fz / fm
        if (i * fz >= fm * (n - cur + 1))
            break;    // 不再枚举更大的分母
        
        // 设定当前分式的分母为 i
        a[cur] = i;
        
        // 剩余分数的分母
        B = fm*i;
        // 剩余分数的分子
        A = fz*i - fm;
        // 求最大公约数
        Gcd = gcd(A, B);
        // 深搜,求下一个分式,而且最小分母是 i + 1,剩余分数的分子分母都约分
        dfs(cur + 1, i + 1, A / Gcd, B / Gcd);
    }
    return;
}

温馨提示:答案为网友推荐,仅供参考