[Copa Blue Bridge] con puntos. Arreglo completo + juicio inteligente

Titulo original

Preguntas de prueba con puntajes de preguntas de prueba anteriores  http://lx.lanqiao.cn/problem.page?gpid=T26

Descripción del problema

100 se puede expresar como un número mixto: 100 = 3 + 69258/714.

También se puede expresar como: 100 = 82 + 3546/197.

Tenga en cuenta la característica: en el número mixto, los números del 1 al 9 aparecen por separado y solo una vez (sin incluir el 0).

Hay 11 representaciones de 100 para números mixtos como este.

Formato de entrada

Leer un entero positivo N de la entrada estándar (N <1000 * 1000)

Formato de salida

El programa genera el número con dígitos del 1 al 9 para formar todos los números representados por números mixtos sin repetición u omisión.

Nota: No es necesario generar todas las representaciones, ¡solo cuente cuántas representaciones hay!

Entrada de muestra 1

100

Salida de muestra 1

11

Entrada de muestra 2

105

Salida de muestra 2

6

análisis

1. Realice un arreglo completo

Los 9 números no se repiten, así que naturalmente pensé en todos los arreglos. 9! = 362 880. Este número exhaustivo se puede completar en 1 segundo. Aquí implemento directamente el arreglo completo mediante el marcado recursivo +. Por supuesto, el siguiente blog de referencia también proporciona una implementación que no es fácil de entender y la eficiencia parece ser un poco mayor.

2. Juzgue inteligentemente si se trata de una ecuación que satisface el significado de la pregunta.

Después de obtener una secuencia de todas las permutaciones, ¿cómo juzgar que la ecuación correspondiente a esta secuencia cumple con el significado de la pregunta?

Hay 9 dígitos en la secuencia, usamos la matriz num [] para instalar, num [0] ~ num [8].

(1) Dado que a <= n, el número de dígitos de a <= el número de dígitos de n

(2) yizhi Enumeramos a de acuerdo con la condición de (1). Y debido a que el último bit de la secuencia num [8] es también el último bit de c. Entonces podemos deducir que el último dígito de b es: bLast = ((na) * num [8])% 10;

(3) Conozca el último dígito de b, luego podemos buscar bLast después de a (la posición inicial puede ser más precisa, porque los dígitos de b> = los dígitos de c). Si existe, se juzga si (b% c == 0 && n == a + b / c) cumple con el significado de la pregunta.

Blog de referencia: http://lx.lanqiao.cn/problem.page?gpid=T26

eficacia

Código 

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;

int n;
int len = 0;

int num[15]; // 存放9个数字的全排列
int vis[15]; // 标志数字在之前是否已使用
int ans = 0;

// [start, end)
int getNum(int start, int end) {
	int t = 0;
	// 1 2 3
	for(int i = start; i < end; i++) {
		t = 10*t + num[i];
	}
		
	return t;
}

void print() {
	for(int i = 0; i < 9; i++)
		printf("%d ", num[i]);
	printf("\n");
}

void dfs(int k) { // 0
	if (k >= 9) {
//		print();
		
		// 得到一个全排列
		for(int i = 1; i <= len; i++) { // a的长度必定在[1, len]
			int a = getNum(0, i);
			// n = a + b / c   =>  b = (n - a) * c
			int bLast = ((n - a)*num[8]) % 10; // b的最后一位
			
			for(int j = (i-1)+ceil((9-i)/2); j < 8; j++) {
				
				if(num[j] == bLast) {
					int b = getNum(i, j+1);
					int c = getNum(j+1, 9);
					
					if(b%c == 0 && n == a + b/c) {
						ans++;	
					}
					
					break;  // 可以提高效率 
				}
			} 
		}

		return;
	}

	for(int i=1; i<=9; i++)
		if(vis[i]==0) { // 数字未被使用
			num[k]=i;  // 填入
			vis[i]=1; // 标记已被使用

			dfs(k+1); // 搜索下一个位置

			num[k]=0;
			vis[i]=0; // 解除标记
		}


}

int main() {
	scanf("%d", &n);

	// 计算n有多少位,a的位数不可能多比n的位数
	int t=n;
	while(t!=0) {
		len++;
		t /= 10;
	}
	
	dfs(0);
	printf("%d\n", ans);

	return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/qq_43290318/article/details/108659028
Recomendado
Clasificación