Со счетом [Кубок Blue Bridge]

описание темы

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)

        Разделите 9 чисел на три числа, используя два цикла for

        Уравнение для оценки соответствия трех чисел требованиям темы

Примечание: нет специального указания, что деление является целочисленным делением, поэтому значение по умолчанию не является целочисленным делением.В настоящее время деления следует избегать, то есть деление становится сложением, вычитанием и умножением.

временная сложность:

        Временная сложность полной аранжировки: 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;
}

Способ 2 (используйте n для уменьшения временной сложности):

         Сначала перечислите a и c и выведите b через отношение между n и a, b и c, то есть 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;
}

Supongo que te gusta

Origin blog.csdn.net/m0_56501550/article/details/129769201
Recomendado
Clasificación