With score [Blue Bridge Cup]

topic description

100 can be expressed as a fraction: 100 = 3 + 69258 / 714.
It can also be expressed as: 100 = 82 + 3546 / 197.
Pay attention to the characteristics: in the band score, the numbers 1~9 appear and only appear once (excluding 0).
With fractions like this, 100 has 11 representations.

input format

Read a positive integer N from standard input (N<1000*1000)

output format

The program outputs the number to form all kinds of numbers represented by fractions with numbers 1 to 9 without repetition.

input sample 

100

Sample output copy

11

That is, n=a+b/c

Method 1 (the most violent approach):

        Full arrangement of 9 numbers (ie 1~9)

        Divide 9 numbers into three numbers using two for loops

        Equation for judging whether three numbers meet the requirements of the topic

Note: There is no special indication that division is integer division, so the default is not integer division. At this time, division needs to be avoided, that is, division becomes addition, subtraction, and multiplication

time complexity:

        The time complexity of full arrangement is: n!*n;

        Put two partitions from the 9 numbers, that is, choose two positions in the eight gaps to place the partitions, that is, divide the 9 numbers into three parts, which is C(8,2)

        So the total time complexity is: n!*n*C(8,2), ie: 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;
}

Method 2 (use n to reduce time complexity):

         Enumerate a and c first, and derive b through the relationship between n and a, b, and c; that is, b=n*cn*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;
}

Guess you like

Origin blog.csdn.net/m0_56501550/article/details/129769201