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