Circle
Accepts: 62
Submissions: 478
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
Fye对约瑟夫游戏十分着迷. 她找到了n个同学,把他们围成一个圈,让他们做约瑟夫游戏,然后她得到了一个同学们出圈的编号序列.游戏是这样进行的:以同学1为起点,开始计数,计数到第k个同学,该同学出圈.出圈的同学将不参与之后的计数. 如今Fye找到了你,她想让你告诉他满足已知出圈序列的最小的k,如果你回答不上来,她就会很生气然后把你吊打一顿.
输入描述
第一行一个数T,为测试数据组数. 对每组测试数据,第一行一个数n. 第二行n个数,为同学的出圈序列(第ai个出圈的人,编号为i). 输入数据必须是一个1到n的合法排列. 1≤T≤10,2≤N≤20.
输出描述
对于每组测试数据,若存在合法的k,输出一个正整数,为合法的最小k,否则输出”Creation August is a SB!“.
输入样例
1 7 7 6 5 4 3 2 1
输出样例
420
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 0x333f3f3f
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))
const ll mod = 1e9 + 7;
const int maxn = 2e5 + 5;
const double PI = acos(-1.0);
ll n, yue;
ll mi[30], ri[30];
ll aa[30], bb[30], dd[30];
void ex_gcd(ll a, ll b, ll &xx, ll &yy)
{
if (b == 0)
{
xx = 1;
yy = 0;
yue = a;
}
else
{
ex_gcd(b, a%b, xx, yy);
ll t = xx;
xx = yy;
yy = t - (a / b)*yy;
}
}
void solve()
{
ll i, j, k;
ll cur_m = mi[1], cur_r = ri[1];
ll f = 0;
repp(i, 2, n)
{
ll xx, yy;
ex_gcd(cur_m, mi[i], xx, yy);
ll c = ri[i] - cur_r;
if (c % yue != 0)
{
puts("Creation August is a SB!");
return;
}
else
{
xx = ((xx* (c / yue)) % (mi[i] / yue) + (mi[i] / yue)) % (mi[i] / yue);
cur_r = xx*cur_m + cur_r;
cur_m = mi[i] / yue*cur_m;
}
}
printf("%lld\n", cur_r > 0 ? cur_r : cur_m);
}
void input()
{
ll i, j, k;
ll x, y;
scanf("%lld", &n);
repp(i, 1, n)
{
aa[i] = i;
scanf("%lld", &k);
bb[k] = i;
}
memset(dd, 0, sizeof(dd));
for (y = 1, i = n; i >= 1; i--)
{
x = bb[n - i + 1];// bb[i]=k表示第i轮淘汰的是k
//cout << i << " " << ((aa[x] - aa[y] + 1) % i + i) % i << endl;
mi[n - i + 1] = i, ri[n - i + 1] = ((aa[x] - aa[y] + 1) % i + i) % i;
//memset(aa, 0, sizeof(aa));
for (dd[x] = 1, k = 0, j = 1; j <= n; j++)
{
if (!dd[j])
{
aa[j] = ++k;
}
}
y = x;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("i.txt", "r", stdin);
freopen("o.txt", "w", stdout);
#endif
int t;
sa(t);
while (t--)
{
input();
solve();
}
return 0;
}