100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
从标准输入读入一个正整数N (N<1000*1000)
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
6
基本思路
这个题只需写出“123456789”的全排列,然后从上面截取运算即可
先普及一个数论知识,a/b=c 若c为x位,b为y位,c为z位,x的最大值为y+z,最小值为x(max)-1
如果设整数位数为bit1,分数部分位数为bit2,分母为x位,分子为y位
,全排列有9位则根据数论知识一定有
x-y=bit2 x+y=9-bit1
算出来x=(9-bit1+bit2)/2 即分母最多有x=(9-bit1+bit2)/2位 最少有(9-bit1+bit2)/2-1位
设n的百分数表示形式为basic+fz/fm
比如当n=100
当basic=1时 分子最多有5位最少有4位
排列数a到了“123456789” ,只需截取两个就可以
a截取为1 2345 6789 发现1+2345/6789!=100舍去
再截取1 23456 789 发现1+23456/789!=100 舍去
当basic=12时 分子最多有4位 最少有3位
排列数a到了“123456789” ,只需截取两个就可以
a截取为12 3456 789 发现12+3456/789!=100舍去
再截取12 345 6789 发现12+345/6789!=100 舍去
当basic=123时
123>100 不再循环
再比如当n=100
排列数a到了“823546197”
当basic=8时,只需两个
截取a截取为8 2354 6197 发现8+2354/6197!=100舍去
再截取8 23546 197 发现8+23546/197!=100 舍去
截取a截取为82 3546 197 发现82+3546/197=100计数器Count+1
再截取82 354 6197 发现82+354/6197!=100 舍去
当basic=823时
823>100 不再循环
至于全排列我没用DFS
我用了stl中的一个输出全排列函数next_permutation(,),这个函数只能对一个字符串a,取a的下一个全排列字符串
具体用法如下:(输出一个字符串所有全排列)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int main()
{
//方法一用char数组
char a[10];
gets(a);
sort(a,a+strlen(a));//因为要输出所有的所以对输入的要进行排序
cout<<a<<endl;
while(next_permutation(a,a+strlen(a)))
cout<<a<<endl;
//方法二用string
cout<<endl;
string s;
cin>>s;
sort(s.begin(),s.end());
cout<<a<<endl;
while(next_permutation(s.begin(),s.end()))
cout<<s<<endl;
return 0;
}
本题我还用到了一个atoi函数
atoi用法如下:
atoi (表示 alphanumeric to integer)是把字符串转换成整型数的一个函数,
原型:int atoi(const char *nptr);
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int Count=0;
char a[10]={'1','2','3','4','5','6','7','8','9',0};
int bits(int num)//求一个数的位数
{
int bit=0;
while(num)
{
bit++;
num/=10;
}
return bit;
}
char *Sub(int s,int e)//截取字符串,从下标s截取到e
{
if(s>e)
return 0;
char *ans=new char;
int k=0;
for(int i=s;i<=e;i++)
ans[k++]=a[i];
ans[k]=0;
return ans;
}
void isval(int num,char seq[],int basic)//判断某一全排列是否有符合要求的截取方案
{
int bit1,bit2,fm,fz;//含义见上面解释
double ans;
char *s1=new char,*s2=new char;
bit1=bits(basic);
bit2=bits(num-basic);
for(int i=(9-bit1+bit2)/2-1;i<=(9-bit1+bit2)/2;i++)//解释见上面,只截取两次
{
fz=atoi(Sub(bit1,bit1+i));
fm=atoi(Sub(bit1+i+1,8));
ans=(fz*1.0)/fm;
if(ans==(double)(num-basic))
Count++;
}
}
int main()
{
int n;
cin>>n;
for(int i=0;i<bits(n);i++)
if(atoi(Sub(0,i))<n)
isval(n,a,atoi(Sub(0,i)));
while(next_permutation(a,a+9))//全排列
for(int i=0;i<bits(n);i++)
if(atoi(Sub(0,i))<n)
isval(n,a,atoi(Sub(0,i)));
cout<<Count<<endl;
return 0;
}