我们知道整数是可以用整数加分数的形式表示的,例如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;
}