#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::steady_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); }
void solve(int n) {
ve<int> perm(n);
iota(all(perm), 1);
shuffle(all(perm), rng);
ve<int> res(n);
for (int i = 0; i < n; ++i) {
ve<int> p;
for (int c = 0; c < n; ++c) {
p.pb(perm[(i + c) % n]);
}
res[i] = query(p);
}
ve<int> df(n);
int s = accumulate(all(res), 0);
for (int i = 0; i < n; ++i) {
df[i] = (s / (n - 1)) - res[i];
}
/*
for (int i = 0; i < n; ++i) {
cout << df[i] << " ";
}
*/
// df[i] = abs(a[i] - a[(i - 1) % n])
ve<int> used(n + 1);
function<void(ve<int>&,int)> rec = [&used,&rec,&n,&df,&perm](ve<int> p, int pos) {
if (pos == n - 1) {
int dif = df[0];
if (abs(p[0] - p[n - 1]) != dif) {
return;
}
/*
for (auto &x : p) {
cout << x << " ";
}
exit(0);
*/
ve<int> ans(n), res;
for (int i = 0; i < n; ++i) {
ans[perm[i] - 1] = p[i];
}
for (auto &x : ans) res.pb(x);
int pmn = min_element(all(res)) - res.begin();
rotate(res.begin(), res.begin() + pmn, res.end());
answer(res);
exit(0);
}
int cur = p[pos];
int Dif = df[(pos + 1) % n];
int sgn = (rng() % 2 == 1 ? 1 : -1);
int dif = Dif * sgn;
if (cur + dif >= 1 && cur + dif <= n && !used[cur + dif]) {
used[cur + dif] = 1;
p[pos + 1] = cur + dif;
rec(p, pos + 1);
p[pos + 1] = -1;
used[cur + dif] = 0;
}
sgn *= -1;
dif = Dif * sgn;
if (cur + dif >= 1 && cur + dif <= n && !used[cur + dif]) {
used[cur + dif] = 1;
p[pos + 1] = cur + dif;
rec(p, pos + 1);
p[pos + 1] = -1;
used[cur + dif] = 0;
}
};
ve<int> p(n, -1);
for (int i = 1; i <= n; ++i) {
int dif = df[i % n];
if ((i + dif >= 1 && i + dif <= n) || (i - dif >= 1 && i - dif <= n)) {
p[0] = i;
used[i] = 1;
rec(p, 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 |
Incorrect |
0 ms |
208 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
0 ms |
208 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
0 ms |
208 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |