蓝桥杯 - 带分数 (DFS)

来源:互联网 发布:nba比赛个人数据统计 编辑:程序博客网 时间:2024/06/05 05:37

  历届试题 带分数  
时间限制: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;}

















1 0