题目:
100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
输入:
从标准输入读入一个正整数N (N< 1000*1000)
输出:
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
👀:
输入:100
输出:11
思路:
- dfs或者STL的next_permutation构建1~9个数的所有排列
- 找出整数,分母,分子各自的位数范围
- 写出由数组位数求出该数的值的算法 (可类比求逆序数的算法)
- 暴力搜索统计
#include<iostream>
using namespace std;
int a[10]={0,1,2,3,4,5,6,7,8,9};
bool book[10];
int total=0,N;
//把获取的数组起终点下标转化成数
int getNum(int x,int y){
int num=0;
for(int i=x;i<=y;i++){
num=num*10+a[i];
}
return num;
}
//判断是否符合等式要求
void judge(int a[]){
int i,j;
//整数位的范围是1~7
for(i=1;i<=7;i++){
//先求整数
int integer=getNum(1,i);
//控制分母范围较好,因为控制分子的话,分母的范围会被降低!!
for(j=(9-i)/2+i;j<=9;j++){
int fz=getNum(i+1,j-1); //分子必须留一位给分母
int fm=getNum(j,9);
if(integer+fz/fm==N&&(fz%fm)==0)
total++;
}
}
}
//求9个数的全排列
void dfs(int step){
if(step==10){
judge(a);
}
for(int i=1;i<=9;i++){
if(book[i]==0){
a[step]=i;
book[i]=1;
dfs(step+1);
book[i]=0;
}
}
}
int main(){
cin>>N;
dfs(1);
cout<<total;
return 0;
}