题目描述
经历十九年的探索,人们终于找到了宇宙中的那份瑰宝。
这份瑰宝被装在一个密码箱里,按照情报,密码应为一串长度为 nn 的数字 aa。
人们满怀希望地输入了密码,但是密码箱没有任何反应。
这时人们意识到,在十九年中,由于宇宙射线的侵蚀,密码箱的密码发生了改变。
现在人们知道,能够打开密码箱的新密码是由原密码 aa 变化而来。具体的,新密码相比原密码变化了 tt 位数字,其中 tt 满足 0≤t≤k0≤t≤k,且对于变化的数字位,变化后的数字是在该位置原数字的基础上增加或减小 11 得到的数字。特别的,如果原数字是 00,在原数字基础上减少 11 得到的数字是 99;如果原数字是 99,在原数字基础上增加 11 得到的数字是 00。
现在人们知道了 n,a,kn,a,k,想知道经过宇宙射线侵蚀后,所有可能打开密码箱的密码。
人类将重任交到了你身上,请你帮助人类解决这个问题。你需要由小到大输出所有可能的密码,每个一行。
特别的,有一些密码可能存在前导 00。为了方便操作,这时你不必也不应将这些前导 00 一并输出。
人类感谢你。
输入格式
输入只有一行三个整数,依次代表原密码位数 nn,去掉前导零后的原密码 aa,和变化位数的最大值 kk。
输出格式
输出若干行,每一行包含一个整数,代表由小到大的所有可能的密码。
输入输出样例
输入 #1
3 14 1
输出 #1
4 13 14 15 24 114 914
#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define fuck(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
using namespace std;
constexpr int N = 1e6 + 10, inf = 0x3f3f3f3f;
vector<int> arr;
set<int>ans;
int temp[N];
int n, a, k;
bool vis[N];
void dfs(int cnt)
{
if (cnt == k)
{
int res = 0;
for (int i = n-1; i>=0; i--)
{
res += temp[i]*pow(10,i);
}
ans.insert(res);
}
for (int i = 0;i < n;i++) {
if (!vis[i]) {
vis[i] = true;
temp[i] += 1;
if (temp[i] == 10) {
temp[i] = 0;
}
dfs(cnt + 1);
temp[i] -= 1;
if (temp[i] == -1) {
temp[i] = 9;
}
vis[i] = false;
}
}
for (int i = 0;i < n;i++) {
if (!vis[i]) {
vis[i] = true;
temp[i] -= 1;
if (temp[i] == -1) {
temp[i] = 9;
}
dfs(cnt + 1);
temp[i] += 1;
if (temp[i] == 10) {
temp[i] = 0;
}
vis[i] = false;
}
}
for (int i = 0;i < n;i++) {
if (!vis[i]) {
vis[i] = true;
dfs(cnt + 1);
vis[i] = false;
}
}
}
void solve()
{
cin >> n >> a >> k;
int temp1 = a;
int cnt = 0;
while (temp1)
{
int u = temp1 % 10;
arr.push_back(u);
temp1 /= 10;
cnt++;
}
int zero = n - cnt;
for (int i = 0; i < zero; i++)
{
arr.push_back(0);
}
for (int i = 0;i < n;i++) {
temp[i] = arr[i];
}
dfs(0);
for (auto it : ans) {
cout << it << endl;
}
}
signed main()
{
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
while (T--)
{
solve();
}
return 0;
}