推出递推公式 f = (f + m - 1) % (2 * k - i);
若超时,需打表;
# include <stdio.h>
# include <stdlib.h>
# include <string>
# include <string.h>
int s[33];
int out(int m, int k) {
int point = -1;
int t = m;
int tmp = k;
while (k --) {
m = t;
while(m --) {
while (!s[(++ point) % (s[30])]);
}
point = point % (s[30]);
//if (s[point] <= tmp) return 0;
printf ("%d ", s[point]);
s[point] = 0;
}
return 1;
}
int pre (int k) {
for (int i = 0; i < k * 2; ++ i) {
s[i] = i + 1;
}
}
int go (int n, int &point, int k) {
while (n --) {
while (!s[(++ point) % (k * 2)]);
}
if(point >= 2 * k)point -= 2 * k;
int t = s[point];
s[point] = 0;
return t;
}
int main () {
int k;
int ans[]={2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881};
memset(s, 0, sizeof(int) * 30);
for(;;) {
scanf ("%d", &k);
if (!k) return 0;printf("%d\n", ans[k - 1]);continue;
s[30] = k * 2;
for (int i = 1; ; ++ i) {
int point = -1;
int j;
pre(k);
for (j = 0; j < k; ++ j) {
int tmp = i % (k * 2 - j);
if (tmp == 0) tmp = 2 * k - j;
if (go(tmp, point, k) <= k) break;
}
if (j == k) {
printf ("%d ", i);
//pre(k);
//out(i, k);
break;
}
/*
int t = i % (k * 2);
if (t <= k && t > 0) continue;
//printf ("%d ", i);
go (k);
if ( out(i, k) ) {
printf ("%d\n", i);
break;
}
*/
}
}
return 0;
}
没打表的:
# include <stdio.h>
# include <stdlib.h>
# include <string>
# include <string.h>
int s[33];
int out(int m, int k) {
int point = -1;
int t = m;
int tmp = k;
while (k --) {
m = t;
while(m --) {
while (!s[(++ point) % (s[30])]);
}
point = point % (s[30]);
//if (s[point] <= tmp) return 0;
printf ("%d ", s[point]);
s[point] = 0;
}
return 1;
}
int pre (int k) {
for (int i = 0; i < k * 2; ++ i) {
s[i] = i + 1;
}
}
int go (int n, int &point, int k) {
while (n --) {
while (!s[(++ point) % (k * 2)]);
}
if(point >= 2 * k)point -= 2 * k;
int t = s[point];
s[point] = 0;
return t;
}
int check(int m, int k) {
int tmp = 0;
for (int i = k * 2; i > k; -- i) {
tmp = (tmp + m - 1) % i;
if (tmp < k) return 0;
}
return 1;
}
int main () {
int k;
memset(s, 0, sizeof(int) * 30);
for(;;) {
scanf ("%d", &k);
if (!k) return 0;
//s[30] = k * 2;
int flag = 0;
int i;
for (int x = 1; ; x++) {
if (check(x * (k + 1),k)) {printf("%d\n", x * (k + 1)); break;};
if (check(x*(k+1) + 1,k)) {printf("%d\n", x* (k + 1) + 1); break;}
/*
flag = 0;
i = x * (k + 1);
here:
//int point = -1;
int j;
int tmp = 0;
//if (tmp <= k && tmp > 0) continue;
//pre(k);
//tmp = 0;
for (j = 0; j < k; ++ j) {
tmp = (i + tmp - 1) % (k * 2 - j);
//if (tmp == 0) tmp = 2 * k - j;
if (tmp < k)break;
//if (go(tmp, point, k) <= k) break;
}
if (j == k) {
printf ("%d ", i);
//pre(k);
//out(i, k);
break;
}
if (!flag) {i = x * (k + 1) + 1; flag = 1;goto here; }
*/
/*
int t = i % (k * 2);
if (t <= k && t > 0) continue;
//printf ("%d ", i);
go (k);
if ( out(i, k) ) {
printf ("%d\n", i);
break;
}
*/
}
}
return 0;
}

1060

被折叠的 条评论
为什么被折叠?



