답안 #703229

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
703229 2023-02-26T16:05:27 Z rainboy 팬케이크 정렬 (NOI12_pancake) C
25 / 25
103 ms 748 KB
#include <stdio.h>

#define N	8
#define N_	40320	/* N_ = N! */

unsigned int X = 12345;

int rand_() {
	return (X *= 3) >> 1;
}

int encode(int *pp, int n);
void decode(int *pp, int n, int k);

int ff[N + 1], dd[N + 1][N_];

void init() {
	static int pp[N_], qq[N_], qu[N_];
	int n, cnt, h, i, j, u, v, d;

	ff[0] = 1;
	for (i = 1; i <= N; i++)
		ff[i] = ff[i - 1] * i;
	for (n = 1; n <= N; n++) {
		for (u = 0; u < ff[n]; u++)
			dd[n][u] = ff[n];
		cnt = 0;
		dd[n][0] = 0, qu[cnt++] = 0;
		for (h = 0; h < cnt; h++) {
			u = qu[h], d = dd[n][u] + 1;
			decode(pp, n, u);
			for (i = 0; i < n; i++) {
				for (j = 0; j < n; j++)
					qq[j] = j < i ? pp[j] : pp[i + n - 1 - j];
				v = encode(qq, n);
				decode(qq, n, v);
				if (dd[n][v] > d)
					dd[n][v] = d, qu[cnt++] = v;
			}
		}
	}
}

int encode(int *pp, int n) {
	int i, p, k, b;

	b = 0, k = 0;
	for (i = 0; i < n; i++) {
		for (p = 0; p < pp[i]; p++)
			if ((b & 1 << p) == 0)
				k += ff[n - 1 - i];
		b |= 1 << pp[i];
	}
	return k;
}

void decode(int *pp, int n, int k) {
	int i, b;

	b = 0;
	for (i = 0; i < n; i++)
		for (pp[i] = 0; pp[i] < n; pp[i]++)
			if ((b & 1 << pp[i]) == 0) {
				if (k < ff[n - 1 - i]) {
					b |= 1 << pp[i];
					break;
				}
				k -= ff[n - 1 - i];
			}
}

int aa[N];

void sort(int *ii, int l, int r) {
	while (l < r) {
		int i = l, j = l, k = r, i_ = ii[l + rand_() % (r - l)], tmp;

		while (j < k)
			if (aa[ii[j]] == aa[i_])
				j++;
			else if (aa[ii[j]] > aa[i_]) {
				tmp = ii[i], ii[i] = ii[j], ii[j] = tmp;
				i++, j++;
			} else {
				k--;
				tmp = ii[j], ii[j] = ii[k], ii[k] = tmp;
			}
		sort(ii, l, i);
		l = k;
	}
}

int main() {
	int t;

	init();
	scanf("%d", &t);
	while (t--) {
		static int pp[N];
		int n, i;

		scanf("%d", &n);
		for (i = 0; i < n; i++)
			scanf("%d", &aa[i]);
		for (i = 0; i < n; i++)
			pp[i] = i;
		sort(pp, 0, n);
		printf("%d\n", dd[n][encode(pp, n)]);
	}
	return 0;
}

Compilation message

pancake.c: In function 'main':
pancake.c:97:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
   97 |  scanf("%d", &t);
      |  ^~~~~~~~~~~~~~~
pancake.c:102:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  102 |   scanf("%d", &n);
      |   ^~~~~~~~~~~~~~~
pancake.c:104:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  104 |    scanf("%d", &aa[i]);
      |    ^~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 97 ms 608 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 93 ms 580 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 93 ms 748 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 96 ms 588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 103 ms 672 KB Output is correct