思路:
要求x位就乘(x - 1)次的意思也就是说,每次乘法加上原序列的各个个位数就是可能的序列里的数字。
然后对除了个位数进行全排列,判断是否可行即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vll;
const int MAXN = 1e6 + 10;
const ll INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1.0);
int n, m, k;
vi p;
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(10) << fixed;
while(cin >> n >> m, n + m){
p.clear();
p.resize(n);
bool found = false;
for(int i = 1; i < m; i++){
p[p.size() - 1] = i;
for(int j = 2; j <= n; j++)
p[p.size() - j] = (i * j) % m;
sort(p.begin(), p.begin() + n - 1);
while(true){
if(p.front()){
found = true;
for(int j = 2; j <= n; j++){
vi temp(n);
for(int t = 0; t < (int)temp.size(); t++)
temp[t] = p[t];
int carry = 0;
for(int t = (int)temp.size() - 1; t >= 0; t--){
temp[t] = (p[t] * j + carry) % m;
carry = (p[t] * j + carry) / m;
}
map<int, int> mp;
for(int t = 0; t < (int)temp.size(); t++)
mp[temp[t]]++;
for(int t = 0; t < (int)p.size(); t++)
mp[p[t]]--;
bool vaild = true;
for(auto it = mp.begin(); it != mp.end(); ++it)
if(it ->second){
vaild = false;
break;
}
if(!vaild){
found = false;
break;
}
}
if(found)
break;
}
if(!next_permutation(p.begin(), p.begin() + p.size() - 1))
break;
}
if(found)
break;
}
if(found){
for(int i = 0; i < (int)p.size(); i++){
if(i)
cout << " ";
cout << p[i];
}
cout << endl;
}
else
cout << "Not found." << endl;
}
cerr << "execute time : " << (double)clock() / CLOCKS_PER_SEC << endl;
return 0;
}
未来可期。