问题描述
100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
输入格式
从标准输入读入一个正整数N (N<1000*1000)
输出格式
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
样例输入1
100
样例输出1
11
样例输入2
105
样例输出2
6
搜索题, 把dfs模板套进去. 再写个check就完事儿了. 详情见代码:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; int tot, n; int use[12]; int red[12]; int getNum(int *p, int len){ //把数组里一定长度的数字转为数值 int ans=0; for(int i=0;i<len;i++) ans = ans*10 + p[i]; return ans; } void check(){ int num1Len, num1, num2, num3,num2Len,num3Len; //num1就是最前面那个加数. num2是分子, num3是分母 for(num1Len = 1;num1Len<8;num1Len++){ num1 = getNum(red, num1Len); if(num1>=n)return;//分式不可能产生负数, 所以 加数 大于等于n的话,直接return for(num2Len = 1;num2Len<8 && num2Len+num1Len<9;num2Len++){ num2 = getNum(&red[num1Len],num2Len); num3Len = 9-num1Len-num2Len; num3 = getNum(&red[num1Len+num2Len], num3Len); if(num2%num3==0 && num2/num3+num1==n)tot++; //注意, 题目里可能没说清楚, 这里的分子除以分母, 结果是个整数, 如果算出来有余数, 就说明这种组合不行. } } } void dfs(int deep) { if(deep==9){ check(); return ; } for(int i=1;i<=9;i++){ if(use[i]==0){ use[i]++; red[deep] = i; dfs(deep+1); use[i]--; } } return ; } int main() { memset(use, 0, sizeof(use)); tot=0; cin>>n; dfs(0); cout<<tot; return 0; }