2022.02.21 带分数(dfs全排列+暴力搜索)

题目复盘

100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。

输入

从标准输入读入一个正整数N (N< 1000*1000)

输出

程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!

样例输入

100  

样例输出

11

思路复盘

首先搞清楚题目要我们做什么,也就是审题,我们需要填入三个未知量,分别是整数、分子、分母。其中每个未知量其中的数字只能出现一次而且1-9全要出现,然后还要满足上述带分数等式。

考虑暴力搜索,但暴力搜索,不单单随便几个for循环就能解决问题的,马克思主义中国化也是需要不断改造才能符合国情,这里也是一样,我们可以发现,整数部分的位数一定要小于7才行,否则分子分母没有数字可填,事实上读者可以将此题当作一个填数字游戏,每个数字卡片只能用一次,这放在我们计算机编程上可以用什么存储结构??最简单的当然是数组。

但是卡片怎么填呢??我们可以把所有的卡片分成三段,分别代表整数、分子、分母,然后逐个位数搜索过去,然后判断了就行了是不是?对的,就是这样的一个思路,然后我们把卡片全排列一下,就可以列举出所有的情况了。

全排列用dfs和剪枝的思想比较快,有兴趣的读者可以参阅之前的dfs博客,这里不再赘述了。

直接看代码把

#include<iostream>
using namespace std;

int n,ans;
int pailie[10],vis[10];

int get_num(int start,int end)
{
    int res=0; //result 考虑如果不写‘=0’会怎么样,本人死在这里
    for(int i=start;i<=end;i++) res=res*10+pailie[i];
    return res;
}

void baoli(int pailie[])
{
//整数部分最多为7位,否则剩下两位就没数字了.
    int zs,fz,fm; //整数,分子,分母
    for(int i=1;i<=7;i++)
    {
        zs=get_num(1,i);
        for(int j=i+(9-i)/2;j<=9;j++){
            int fz=get_num(i+1,j-1); //分子必须留一位给分母
            int fm=get_num(j,9);
            if(zs+fz/fm==n&&(fz%fm)==0) ans++;
        }
    }

}

void dfs(int h)
//全排列
{
    if(h==10)
    {
        baoli(pailie);
    }
    else
    {
        for(int i=1;i<=9;i++)
        {
            if(vis[i]==0)
            {
                vis[i]=1;
                pailie[h]=i;
                dfs(h+1);
                vis[i]=0;
            }
        }
    }
}

int main()
{
    cin>>n;
    dfs(1);
    cout<<ans<<endl;
    return 0;
}

end...关注后续更新~

posted @ 2022-02-22 23:30  yuezi2048  阅读(20)  评论(0编辑  收藏  举报