思路
直接枚举a、c,b就可直接判断出来(优化)
先枚举a,若a存在则枚举c,对于每一个枚举的a、c去判断b是否成立(是否符合题目)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 20;
int n;
int ans;//答案
bool st[N];//判别使用
bool backup[N];//判重数组
bool check(int a, int c) {
int b = n * c - a * c;//题目得到b
if (!a || !b || !c) return false;//a,b,c都不可为0
memcpy(backup, st, sizeof st);//将长度为sizeof st的数组st复制到数组backup中
while (b)//检查b的每位数是否符合
{
int x = b % 10;//得到个位b
b /= 10;//去掉个位
if (!x || backup[x]) return false;//!x代表x为零,backup[x]代表x出现过,不符合题目
else backup[x] = true;//代表当前位可取,改变状态
}
//检查所有数字是否全部使用
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 + 1) return;
if (check(a, c)) ans++;//符合要求累加可能
//全排列c的可能
for (int i = 1; i <= 9; i++) {
if (!st[i]) {
st[i] = true;
dfs_c(u + 1, a, c * 10 + i);//a不变,c进位增加
st[i] = false;//恢复现场
}
}
}
void dfs_a(int u, int a) //u表示当前用了几个数字,a代表数学大小数字
{
if (a >= n)return;
dfs_c(u, a, 0);//减枝,当a存在时再计算c
//全排列a的可能
for (int i = 1; i <= 9; i++) {
if (!st[i]) {
st[i] = true;
dfs_a(u + 1, a * 10 + i);//a进一位再加上数,例如12到123
st[i] = false;//恢复现场
}
}
}
int main() {
cin >> n;
dfs_a(0, 0);//最开始
cout << ans << endl;
return 0;
}