蓝桥杯 带分数

    xiaoxiao2021-04-03  54

    问题描述

    100 可以表示为带分数的形式:100 = 3 + 69258 / 714。

    还可以表示为:100 = 82 + 3546 / 197。

    注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。

    类似这样的带分数,100 有 11 种表示法。

    输入格式

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

    输出格式

    程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。

    注意:不要求输出每个表示,只统计有多少表示法!

    样例输入1 100 样例输出1 11 样例输入2 105 样例输出2

    6

    刚开始看这道题觉得有点麻烦,想的是把1-9分成3部分,然后每次字典序排序,非常麻烦,后来看了网上的题解,觉得用DFS更容易去做。

    首先取整数部分,然后取分母部分,输入与整数的差乘以分母则为分子,只要满足分子为取过整数和分母之后剩下的数字组成的要求,即为一种表示法。

    整数部分取到n-2即可。n-1时,分子与分母要相等,不可能,舍弃。n时,分子为0,不可能,舍弃。

    代码如下:

    [html]  view plain  copy #include<cstdio>   #include<cstring>      int flag1[10],flag2[10];   int ls,v,num=0;      int check(int n)   //检查该数字组成中是否有重复的数字,若没有,将出现过的数字做标记,并返回1,否则返回0;    {       int i;       ls=0;       while(n)       {           i=n;           if(flag1[i])           return 0;           flag1[i]=1;           n/=10;           ls++;       }       ls=9-ls;     //储存未被标记的数字的个数        return 1;   }      int judge(int n)    //check功能相同,检查是否有重复,并返回该数字长度    {       int i,len=0;       memcpy(flag2,flag1,sizeof(flag2));       while(n)       {           i=n;           if(flag2[i])           return 0;           flag2[i]=1;           n/=10;           len++;       }       return len;   }      void dfs(int len,int x)   //X作为分母 len作为分母的长度    {       if(judge(x*v)==ls-len) //分子为分母和n与整数部分之差的乘积    若分子长度与分母长度之和为剩下的长度,则所有数字均被使用,且无重复        {           num++;       }       if(len<=ls/2)       for(int i=1;i<10;i++)       {           if(!flag1[i])           {               flag1[i]=1;               dfs(len+1,x*10+i);               flag1[i]=0;           }       }   }      int main()   {       int n;       scanf("%d",&n);       for(int i=1;i<n-1;i++)       //从1开始,遍历取整数部分,取到n-2为止。        {           memset(flag1,0,sizeof(flag1));           flag1[0]=1;           if(check(i))           {               v=n-i;               dfs(0,0);           }       }       printf("%d",num);   }  
    转载请注明原文地址: https://ju.6miu.com/read-665902.html

    最新回复(0)