首页 > 技术文章 > [蓝桥杯][历届试题]带分数

zuimeiyujianni 2018-04-06 17:03 原文

时间限制: 1Sec 内存限制: 128MB 提交: 46 解决: 31

题目描述
100  可以表示为带分数的形式:100  =  3  +  69258  /  714。 
还可以表示为:100  =  82  +  3546  /  197。 
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。 
类似这样的带分数,100  有  11  种表示法。 
输入
从标准输入读入一个正整数N  (N< 1000*1000) 
输出
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。 
注意:不要求输出每个表示,只统计有多少表示法! 
样例输入
100  
样例输出
11

/*

 首先是进行全排列,然后根据全排列的结果枚举x,y,z

    x的长度为1-7

    y的最短长短是:(9-x的长度)/2 ,最长的长度:8-x的长度
    z的长度是剩下的长度,至少为一个长度。

  */

#include<cstdio>
#include<iostream>
using namespace std;
int vis[10];
int a[10],ans,n;
long long  num(int s,int e){
    long long sum = 0;
    for(int i=s;i<=e;i++) sum = sum*10+a[i];
    return sum;
} 
void dfs(int cur)
{
    if(cur == 10)
    {
        //for(int i=1;i<=9;i++) printf("%d",a[i]);
        //printf("\n");
        for(int i=1;i<=7;i++)
        {
            long long x = num(1,i);
            int len = (9-i)/2; //y的最短长度 
            for(int j=len;j<=8-i;j++)
            {
                long long y=num(i+1,i+j); 
                long long z=num(i+j+1,9);
                //printf("%d = %d + %d/%d\n",n,x,y,z);
                if(y%z == 0 && x+y/z==n) ans++;
            } 
        } 
        return ;
    }
    for(int i=1;i<=9;i++)
    if(!vis[i])
    {
        vis[i]=1;
        a[cur]=i;
        dfs(cur+1); 
        vis[i]=0;
    }
}
int main(void)
{
    scanf("%d",&n);
    dfs(1);
    printf("%d",ans);
    return 0;
}

 

推荐阅读