[Blue Bridge Cup] avec des points. Arrangement complet + jugement intelligent

Titre original

Questions de test avec les résultats des questions de test précédentes  http://lx.lanqiao.cn/problem.page?gpid=T26

Description du problème

100 peut être exprimé sous la forme d'un nombre mixte: 100 = 3 + 69258/714.

Il peut également être exprimé comme suit: 100 = 82 + 3546/197.

Notez la fonctionnalité: dans le nombre mixte, les nombres 1 à 9 apparaissent séparément et une seule fois (sans 0).

Il y a 11 représentations de 100 pour des nombres mixtes comme celui-ci.

Format d'entrée

Lire un entier positif N à partir de l'entrée standard (N <1000 * 1000)

Format de sortie

Le programme sort le nombre avec les chiffres 1 ~ 9 pour former tous les nombres représentés par des nombres mixtes sans répétition ni omission.

Remarque: il n'est pas nécessaire de sortir chaque représentation, ne comptez que le nombre de représentations qu'il y a!

Exemple d'entrée 1

100

Exemple de sortie 1

11

Exemple d'entrée 2

105

Exemple de sortie 2

6

une analyse

1. Réaliser un arrangement complet

Les 9 numéros ne sont pas répétés, donc j'ai naturellement pensé à tous les arrangements. 9! = 362 880. Ce nombre exhaustif peut être complété en 1 seconde. Ici, j'implémente directement l'arrangement complet par marquage + récursif. Bien sûr, le blog de référence suivant fournit également une implémentation qui n'est pas facile à comprendre, et l'efficacité semble être un peu plus élevée.

2. Juger habilement si c'est une équation qui satisfait le sens de la question

Après avoir obtenu une séquence de toutes les permutations, comment juger que l'équation correspondant à cette séquence répond au sens de la question?

Il y a 9 chiffres dans la séquence, nous utilisons le tableau num [] pour installer, num [0] ~ num [8].

(1) Puisque a <= n, le nombre de chiffres de a <= le nombre de chiffres de n

(2) yizhi Nous énumérons a selon la condition de (1). Et parce que le dernier bit de la séquence num [8] est aussi le dernier bit de c. On peut donc en déduire que le dernier chiffre de b est: bLast = ((na) * num [8])% 10;

(3) Connaissez le dernier chiffre de b, alors nous pouvons rechercher bLast après a (la position de départ peut être plus précise, car les chiffres de b> = les chiffres de c). S'il existe, on juge si (b% c == 0 && n == a + b / c) répond au sens de la question.

Blog de référence: http://lx.lanqiao.cn/problem.page?gpid=T26

efficacité

Code 

#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;
}

 

Je suppose que tu aimes

Origine blog.csdn.net/qq_43290318/article/details/108659028
conseillé
Classement