【题目大意】
给定一个N(2≤N≤79),用0-9这10个数字,组成两个五位数(可以有前导零),这10个数字必须全部使用且仅使用一次,使得这两个数的商为N。
【解法】
1.dfs找出0-9其中的5个数所形成的五位数(四位数)N1
2.用第一步找出的这些N1乘以N,得到N2
3.判断N1、N2所有出现的数字次数都出现且仅出现一次
4.符合则输出
【坑点】
1.每两组输出中间输出空行,最后一个没有
2.前导零也需要输出
【AC代码】
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int N;
int mark;
int a[10];
int vis[10];
int vvis[15];
void check(){ ///输出在数组a中已经填好的排列数
int temp = 0;
// for(int i = 1; i <= 5; i++){
// printf("%d ", a[i]);
// }
// printf("\n");
for(int i = 1; i <= 5; i++){
temp = temp * 10 + a[i];
}
int temp1 = temp * N;
if(temp * N > 98765){
return ;
}
else{
// printf("%d\n", temp);
// printf("%d\n", temp1);
memset(vvis, 0, sizeof(vvis));
for(int i = 1; i <= 5; i++){
vvis[ a[i] ] = 1;
}
// for(int i = 0; i < 10; i++){
// printf("%d:%d ", i, vvis[i]);
// }
// printf("\n");
int copytemp1 = temp1;
while(temp1){
int res = temp1 % 10;
// printf("res = %d\n", res);
if(vvis[ res ] == 0){
vvis[res] = 1;
temp1 /= 10;
}
else if(vvis[res] == 1){
return ;
}
}
// for(int i = 0; i < 10; i++){
// printf("%d:%d ", i, vvis[i]);
// }
// printf("\n");
mark = 1;
if(copytemp1 < 10000 && temp < 10000){
return ;
// printf("0%d / 0%d = %d\n", copytemp1, temp, N);
}
else if(copytemp1 < 10000 && temp > 10000){
printf("0%d / %d = %d\n", copytemp1, temp, N);
}
else if(copytemp1 > 10000 && temp < 10000){
printf("%d / 0%d = %d\n", copytemp1, temp, N);
}
else if(copytemp1 > 10000 && temp > 10000){
printf("%d / %d = %d\n", copytemp1, temp, N);
}
}
}
void dfs(int depth){ ///正在搜索第depth个数
if(depth == 6){ ///已经填好5个数了
check(); ///确认填好的5个数
return;
}
for(int i = 0; i <= 9; i++){///枚举所有可以用的数
if(!vis[i]){ ///当前这个数还没被用过
a[depth] = i; ///将当前数存在a数组中的第depth个位置
vis[i] = 1; ///标记该数已经用过
dfs(depth + 1); ///搜索下一层
vis[i] = 0; ///回溯,将该数的标记标为尚未用过
}
}
}
int main(){
// freopen("stdout.txt", "w", stdout);
int one = 1;
while(scanf("%d", &N) != EOF && N){
if(one == 1){
one++;
}
else{
printf("\n");
}
mark = 0;
dfs(1); ///搜第一个数
if(mark == 0){
printf("There are no solutions for %d.\n", N);
}
}
return 0;
}