思路:
递归依次枚举三个数,
或者枚举a,cb可以通过a和c得到
注意:
1、a,b,c的范围,a不能超过n且不能为0,b和c都不能为0
2、判断b的时候把状态数组copy一下,如果b判断不成功的话,就不用再恢复原数组了
3、递归完成都要恢复原状态
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 20;//注意写N的范围,不然会超时运行不出来
int n, state[N],backup[N];
int ans = 0;
bool check_b(int a , int c){
int b = c * n - a * c;
//printf("b = %d\n",b);
if(b == 0) return false;//注意判断b的范围,b不能为0
//不然会卡14那个数据
memcpy(backup, state, sizeof(state));
while(b){
int x = b % 10;
b /= 10;
if( !x || backup[x]) return false;//b中出现0或者是跟a和c重复的数字,返回false
backup[x] = 1;
}
for( int i = 1; i <= 9; i++){
if(backup[i] == 0) return false;
}
return true;
}
void dfs_c(int a, int c){
//printf("c = %d,",c);
if(c){//注意判断c的范围,c不能为0
if(check_b(a,c)){
ans++;
}
}
for(int i = 1; i <= 9; i++){
if(state[i] == 0){
state[i] = 1;
dfs_c(a , c * 10 + i);
state[i] = 0;
}
}
}
void dfs_a(int a){
//printf("a = %d,",a);
if(a > n) return;
if(a) dfs_c(a, 0);//注意判断a的范围,a不能为0
for(int i = 1; i <= 9; i++){
if(state[i] == 0){
state[i] = 1;
dfs_a(a * 10 + i);
state[i] = 0;
}
}
}
int main(){
scanf("%d",&n);
dfs_a(0);
printf("%d",ans);
return 0;
}