链接:https://www.cnblogs.com/longwind7/p/15531056.html
题目:
100 可以表示为带分数的形式:
还可以表示为:
注意特征:带分数中,数字 1∼9 分别出现且只出现一次(不包含 0)。
类似这样的带分数,100 有 11 种表示法。
输入格式
一个正整数。
输出格式
输出输入数字用数码 1∼9 不重复不遗漏地组成带分数表示的全部种数。
数据范围
1≤N<106
输入样例1:
100
输出样例1:
11
输入样例2:
105
输出样例2:
6
思路:
给定一个数N,问有多少组a,b,c满足,且a,b,c三个数不重不漏地涵盖1−9这9个数字,输出总组数
暴力枚举出9个数的全排列,然后用一个长度为9的数组保存全排列的结果
从全排列的结果中用两重循环暴力分解出三段,每段代表一个数
验证枚举出来的三个数是否满足题干条件,若满足则计数
题解:
#include <bits/stdc++.h>
using namespace std;
const int N=20; //需要提前预设的变量:保存答案的数组,used数组
int ways[N]; //保存全排列
bool used[N]; //判断是否可用
int n,ans; //n为输入,ans为答案个数
int f(int a,int b) //将分好的一段数字转换成int
{
int sum=0;
for(int i=a;i<=b;i++)
sum=sum*10+ways[i];
return sum;
}
void dfs(int u)
{
if(u>9) //全排列已完成
{
if(f(1,i)>n) break; //剪枝,当a大于n时,一定无解,直接跳出
for(int i=1;i<=7;i++) //暴力枚举,两重循环把九位数字分成三段
{
for(int j=i+1;j<=8;j++)
{
if(j-i<9-i) continue; //剪枝,当b的位数小于c的位数时,分数小于1,一定不为整数,跳出
int a=f(1,i);
int b=f(i+1,j);
int c=f(j+1,9);
if(b==n*c-a*c) ans++;
}
}
return;
}
for(int i=1;i<=9;i++)
{
if(!used[i]) //如果该数字没有被用过
{
used[i]=true;
ways[u]=i;
dfs(u+1);
used[i]=false; //恢复现场
ways[u]=0;
}
}
}
int main()
{
cin>>n;
dfs(1);
cout<<ans;
return 0;
}