带分数[蓝桥杯]

时间:2023-04-02 07:34:00

题目描述

100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。

输入格式

从标准输入读入一个正整数N (N<1000*1000)

输出格式

程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。

输入样例 

100

输出样例 复制

11

即n=a+b/c

方法1(最暴力的做法):

        全排列9个数字(即1~9)

        使用两个for循环将9个数字分割成三个数

        判断三个数是否符合题目要求的等式

注:除法没有特殊说明是整除,所以默认不是整除,此时需要避免除法,即将除法变成加减乘

时间复杂度:

        全排列的时间复杂度是:n!*n;

        从9个数里面放两个隔板,即在八个空挡里面选两个位置放隔板,即将9个数分成三份,是C(8,2)

        所以总的时间复杂度为:n!*n*C(8,2),即:9!*9*8*7/2=91445760

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
bool vis[10];
int n,an[10],ans;
int xten(int l,int r) {
	int temp=0;
	for(int i=l; i<=r; i++) {
		temp=temp*10+an[i]+1;
	}
	return temp;
}
void dfs(int q) {
	if(q==9) {
		for(int i=0; i<=6; i++) {
			for(int j=i+1; j<=7; j++) {
				int a=xten(0,i);
				int b=xten(i+1,j);
				int c=xten(j+1,8);
				if(c*(n-a)==b) ans++;
			}
		}
		return ;
	}
	for(int i=0; i<9; i++) {
		if(!vis[i]) {
			vis[i]=true;
			an[q]=i;
			dfs(q+1);
			vis[i]=false;
		}
	}
}
int main() {
	scanf("%d",&n);
	dfs(0);
	printf("%d\n",ans);
	return 0;
}

方法二(利用n减少时间复杂度):

         先枚举a和c,通过n与a、b、c的关系推出b;即b=n*c-n*a;

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=20;
int n;
bool st[N],backup[N];
int ans=0;
bool check(int a,int c) {
	int b=n*c-a*c;
	if(!a||!b||!c)return false;
	memcpy(backup,st,sizeof(st));
	while(b) {
		int x=b%10;
		if(!x||backup[x])return false;
		backup[x]=true;
		b/=10;
	}
	for(int i=1; i<=9; i++) {
		if(!backup[i])
			return false;
	}
	return true;
}
void dfs_c(int u,int a,int c) {
	if(u==9)return;
	if(check(a,c)) {
		ans++;
	}
	for(int i=1; i<=9; i++) {
		if(!st[i]) {
			st[i]=true;
			dfs_c(u+1,a,c*10+i);
			st[i]=false;
		}
	}
}
void dfs_a(int u,int a) {
	if(a>=n) return ;
	if(a) dfs_c(u,a,0);
	for(int i=1; i<=9; i++) {
		if(!st[i]) {
			st[i]=true;
			dfs_a(u+1,a*10+i);
			st[i]=false;
		}
	}
}
int main() {
	cin>>n;
	dfs_a(0,0);
	cout<<ans<<endl;
	return 0;
}