Submission #685467

# Submission time Handle Problem Language Result Execution time Memory
685467 2023-01-24T12:10:16 Z vovamr Secret Permutation (RMI19_permutation) C++17
0 / 100
0 ms 208 KB
#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);
      |   ~~~~~~^~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 208 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 208 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 0 ms 208 KB Output isn't correct
2 Halted 0 ms 0 KB -