#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include "permutation.h"
#pragma GCC optimize("-O3")
#pragma GCC optimize("unroll-loops")
#define fi first
#define se second
#define ll long long
#define ld long double
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mpp make_pair
#define ve vector
using namespace std;
using namespace __gnu_pbds;
template<class T> using oset = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
const ll inf = 1e18; const int iinf = 1e9;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
template <typename T> inline bool chmin(T& a, T b) { return (a > b ? a = b, 1 : 0); }
template <typename T> inline bool chmax(T& a, T b) { return (a < b ? a = b, 1 : 0); }
const int N = 300;
int nn;
ve<int> perm;
int p[N];
int res[N], df[N], used[N];
const int Z = 1;
ve<ve<int>> rnd_perm;
ve<int> rnd_res;
inline void rec(int pos) {
if (pos == nn - 1) {
int dif = df[0];
if (abs(p[0] - p[nn - 1]) != dif) {
return;
}
ve<int> res(nn), ress(nn);
for (int i = 0; i < nn; ++i) res[perm[i] - 1] = p[i];
for (int i = 0; i < nn; ++i) ress[i] = res[i];
for (int id = 0; id < Z; ++id) {
ve<int> pe = rnd_perm[id];
int ans_jury = rnd_res[id];
int ans_mine = 0;
for (int i = 0; i < nn - 1; ++i) {
ans_mine += abs( ress[pe[i] - 1] - ress[pe[i + 1] - 1] );
}
if (ans_jury != ans_mine) {
return;
}
}
answer(ress);
}
int cur = p[pos];
int dif = df[(pos + 1) % nn];
if (cur + dif >= 1 && cur + dif <= nn && !used[cur + dif]) {
used[cur + dif] = 1;
p[pos + 1] = cur + dif;
rec(pos + 1);
p[pos + 1] = -1;
used[cur + dif] = 0;
}
if (cur - dif >= 1 && cur - dif <= nn && !used[cur - dif]) {
used[cur - dif] = 1;
p[pos + 1] = cur - dif;
rec(pos + 1);
p[pos + 1] = -1;
used[cur - dif] = 0;
}
}
void solve(int n) {
if (n == 1) {
answer(ve<int>{1});
}
perm.resize(n);
iota(all(perm), 1);
int I = n * (n - 1) / 2;
int ivl = 10;
int ivr = I - 10;
if (ivl > ivr) ivl = 0, ivr = I;
while (1) {
shuffle(all(perm), rng);
int inv = 0;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
inv += (perm[i] > perm[j]);
}
}
if (inv >= ivl && inv <= ivr) break;
}
rnd_res.resize(Z);
rnd_perm.resize(Z);
nn = n;
ve<int> pe(n);
for (int i = 0; i < n; ++i) {
for (int c = 0; c < n; ++c) {
pe[c] = perm[(i + c) % n];
}
res[i] = query(pe);
}
rnd_perm[0] = perm;
rnd_res[0] = res[0];
for (int id = 1; id < Z; ++id) {
ve<int> pe(n);
iota(all(pe), 1);
shuffle(all(pe), rng);
rnd_perm[id] = pe;
rnd_res[id] = query(pe);
}
int s = accumulate(res, res + n, 0);
for (int i = 0; i < n; ++i) {
df[i] = (s / (n - 1)) - res[i];
}
ve<int> F(n);
iota(all(F), 1);
shuffle(all(F), rng);
for (const auto &i : F) {
int dif = df[1];
if ((i + dif >= 1 && i + dif <= n) || (i - dif >= 1 && i - dif <= n)) {
p[0] = i;
used[i] = 1;
rec(0);
used[i] = 0;
p[0] = -1;
}
}
}
#ifdef LOCAL
namespace A {
int N;
const int MAX_N = 1000;
int P[1 + MAX_N];
int queries = 0;
void readInput() {
//printf("The permutation you have to guess is:\n");
scanf("%d", &N);
for (int i = 1; i <= N; i++) {
scanf("%d", &P[i]);
//printf("%d ", P[i]);
}
//printf("\n");
}
int query(int V[]) {
queries++;
printf("query(");
for (int i = 0; i < N - 1; i++) {
printf("%d, ", V[i]);
}
printf("%d) = ", V[N - 1]);
int freq[1 + N];
for (int i = 0; i <= N; i++) {
freq[i] = 0;
}
for (int i = 0; i < N; i++) {
freq[V[i]]++;
}
for (int i = 1; i <= N; i++) {
assert(freq[i] == 1);
}
int answer = 0;
for (int i = 0; i + 1 < N; i++) {
answer += abs(P[V[i + 1]] - P[V[i]]);
}
printf("%d\n", answer);
fflush(stdout);
return answer;
}
void answer(int V[]) {
bool ok = true;
ve<int> p(N);
iota(all(p), 1);
do {
int ans_jury = 0;
for (int i = 0; i < N - 1; ++i) ans_jury += abs(P[p[i]] - P[p[i + 1]]);
int ans_mine = 0;
for (int i = 0; i < N - 1; ++i) ans_mine += abs(V[p[i] - 1] - V[p[i + 1] - 1]);
ok &= (ans_jury == ans_mine);
if (!ok) break;
} while (next_permutation(all(p)));
if (ok) {
printf("Correct! with N = %d, Q = %d\n", N, queries);
} else {
printf("Wrong answer!\n");
}
exit(0);
}
}
int query(int p[]) {
return A::query(p);
}
void answer(int ans[]) {
A::answer(ans);
}
int query(std::vector<int> v) {
int array[A::N];
for (int i = 0; i < A::N; i++) {
array[i] = v[i];
}
return query(array);
}
void answer(std::vector<int> v) {
int array[A::N];
for (int i = 0; i < A::N; i++) {
array[i] = v[i];
}
answer(array);
}
int main(int argc, char **argv) {
A::readInput();
solve(A::N);
return 0;
}
#endif
Compilation message
stub.cpp: In function 'int query(int*)':
stub.cpp:15:9: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
15 | fscanf(stdin, "%d", &x);
| ~~~~~~^~~~~~~~~~~~~~~~~
stub.cpp: In function 'int main(int, char**)':
stub.cpp:48:9: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
48 | fscanf(stdin, "%d", &N);
| ~~~~~~^~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
208 KB |
Output is correct |
2 |
Correct |
1 ms |
208 KB |
Output is correct |
3 |
Incorrect |
0 ms |
208 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
208 KB |
Output is correct |
2 |
Correct |
1 ms |
208 KB |
Output is correct |
3 |
Incorrect |
0 ms |
208 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
208 KB |
Output is correct |
2 |
Correct |
1 ms |
208 KB |
Output is correct |
3 |
Incorrect |
0 ms |
208 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |