蓝桥杯 - 带分数 (DFS)

Posted slgkaifa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯 - 带分数 (DFS)相关的知识,希望对你有一定的参考价值。

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

















以上是关于蓝桥杯 - 带分数 (DFS)的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯历届试题 正则问题(非dfs解决)

15年蓝桥杯第5题

java 蓝桥杯 dfs 全排列

[蓝桥杯]带分数

[蓝桥杯] 带分数

带分数 -- 蓝桥杯