分数表示法

我们知道整数是可以用整数加分数的形式表示的,例如5=3+9562/4781=3+9712/4856=3+2956/1478=3+9172/4586=2+9762/3254等等 其中1~9只在前4种的整数部分和分子分母出现且只出现一次,我们求这样的式子的个数即test(x),其中65535>x>0,例如test(5)=4。 输入描述: 输入的第一行是一个整数N<10000,表示数据组数,接下来N行,每行包含一个正整数x。 输出描述: 对于每个x,输出test(x)。

根据本题要求,需要对1-9进行全排列,然后在处理筛选出符合要求的数。首先 说全排列问题,要用到next_permutation()函数,有关讲解请看http://blog.csdn.net/u014794992/article/details/40370817

下面直接在代码中有讲解:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int l[65535+5]= {0};
void cn(int a[])//本题x最大取值为65535为5位数,表达式为x==a+b/c
{//i,j,k表示长度/位数
    for(int i = 1 ; i <= 5 ; i ++) //i表示a的位数,最大为5位,
        for(int j = 1; j <= 8 - i ; j++){//本题一共有9位数,分母c不能为0,至少占一位数
            //因此b的位数最大范围为8-i
            int k = 9 - i - j;//当a和b的位数确定后,剩下的为C的位数,9-i-j
            if(j<k)//b/c必为整数,因此b的位数若小于c直接跳过
                continue;
            int x = 0, y =0 ,z = 0;//设x,y,z 表示a,b,c的值
            for(int t = 0 ; t < i ; t++){//求x值过程
                x*=10;
                x+=a[t];
            }
            for(int p = i ,q = 0 ; q < j ; q++,p++ ){//求y
                y*=10;
                y+=a[p];
            }
            for(int r = i+j ,s = 0 ; s < k ; s++,r++){//求z
                z*=10;
                z+=a[r];
            }
            if(y%z!=0) continue;//若y/z不能整除,进行下一次计算
            if(x+y/z <= 65535){//符合条件
                l[x+y/z]++;  //统计次数+1
            }
        }
}
void text()//用next_permutation()求1-9的全排列
{
    int f[10]= {1,2,3,4,5,6,7,8,9};
    do{
        cn(f);
    }
    while(next_permutation(f,f+9));
}
int main()
{
    int n,x;
    memset(l,0,sizeof(l));
    text();//打表
    while(scanf("%d",&n)!=EOF)
    {
        while(n--)
        {
            scanf("%d",&x);
            printf("%d\n",l[x]);
        }
    }
    return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值