历届试题 带分数  
时间限制:1.0s   内存限制:256.0MB
      
问题描写叙述

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,先枚举整数部分,然后再DFS枚举分母就可以



AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std; int flag[20], n;
int ans;
int ll;//ll为去掉整数位数而剩下的位数
int v;//v为分数的整数值) int fun(int x) {
int len = 0;
while(x) {
int t = x % 10;
if(flag[t]) return 0;
flag[t] = 1;
x /= 10;
len++;
}
ll = 9 - len;
return 1;
} int judge(int x, int l) {
int len = 0;
int a[20];
memcpy(a, flag, sizeof(flag));
while(x) {
int t = x % 10;
if(a[t]) return 0;
a[t] = 1;
x /= 10;
len ++;
}
int ff = 1;
for(int i = 1; i < 10; i++) {//看数字1到9是否都用到了
if(a[i] == 0) ff = 0;
} if(ff && len == ll - l) return 1;
return 0;
} void dfs(int len, int x) { //len为此时分母所占的位数。x为分母
if(len <= ll / 2) {
if(judge(v * x, len)) //v*x为分子
ans ++;
for(int i = 1; i < 10; i++) {
if(flag[i]) continue;
flag[i] = 1;
dfs(len + 1, x * 10 + i);
flag[i] = 0;
}
}
} int main() {
while(cin >> n) {
ans = 0;
for(int i = 1; i < n; i++) {
memset(flag, 0, sizeof(flag));
if(fun(i)) {
v = n - i;
dfs(0, 0);
}
} cout << ans << endl;
}
return 0;
}

05-11 11:05