难度:2
这道题,直接暴力应该也能过,但是看完枚举子集,回过头来,就有了这种思路,就是书上说的,先找第一个被除数,然后再去找有没有满足条件的除数,先枚举个数为5的0到9的子集,然后这个子集枚举出来,用它全排列,构成了第一个数,然后再去找第二个数就行了,总之思路就是先枚举子集然后全排列,代码也不短。
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pa;
int num;
vector<pa> res;
void solve(int *b, int cur, int n, int cnt) {
if (cur == n) {
if (cnt == 5) {
vi v;
set<int> st;
for (int i = 0; i < n; i++) {
if (b[i]) {
v.pb(i);
st.insert(i);
}
}
do {
int x1 = 0;
for (int i = 0; i < 5; i++) {
x1 = x1 * 10 + v[i];
}
if (x1 % num == 0) {
set<int> st2 = st;
int x2 = x1 / num;
if (x2 < 10000) st2.insert(0);
int t = x2;
while (t) {
st2.insert(t % 10);
t /= 10;
}
if ((int) st2.size() == 10) {
res.pb(make_pair(x1, x2));
}
}
} while (next_permutation(all(v)));
}
return;
}
b[cur] = 1;
solve(b, cur + 1, n, cnt + 1);
b[cur] = 0;
solve(b, cur + 1, n, cnt);
}
bool cmp(pa a, pa b) {
return a.fi < b.fi;
}
int main() {
int cnt = 0;
while (cin >> num && num) {
res.clear();
int b[15];
solve(b, 0, 10, 0);
sort(all(res), cmp);
cout << (cnt++ ? "\n" : "");
if ((int) res.size() == 0) cout << "There are no solutions for " << num << ".\n";
else {
for (int i = 0; i < (int) res.size(); i++) {
printf("%05d / %05d = %d\n", res[i].fi, res[i].se, num);
}
}
}
return 0;
}