您的位置:首页 > 其它

HDU 5668 Circle (约瑟夫游戏,求解同余方程组)

2016-04-25 09:36 113 查看
样例:

1

7

7 6 5 4 3 2 1



题解:约瑟夫环问题,可以转换成中国剩余定理,然后就是套模板了。好坑啊,我每轮游戏都从第一个人开始计数。。而且题意也理解错了。。输入是代表第一个人第七轮游戏才出局,而不是第七个人第一轮游戏出局。。。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF  0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-9
#define maxn 100010
#define MOD 1000000007

int num[22],m[22],a[22],c[22];
long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
if(a == 0 && b == 0)
return -1;
if(!b)
{
x = 1;
y = 0;
return a;
}
long long d = extend_gcd(b,a%b,y,x);
y -= a/b*x;
return d;
}
bool solve(int &m0,int &a0,int m,int a)
{
long long y,x;
int g = extend_gcd(m0,m,x,y);
if(abs(a-a0)%g)
return 0;
x *= (a - a0) / g;
x %= m/g;
a0 = (x*m0 + a0);
m0 *= m/g;
a0 %= m0;
if(a0 < 0)
a0 += m0;
return 1;
}
bool MLSE(int &m0,int &a0,int n)
{
bool flag = 1;
m0 = 1;
a0 = 0;
for(int i = 0; i < n; i++)
if(!solve(m0,a0,m[i],a[i]))
{
flag = 0;
break;
}
return flag;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,flag[22];
memset(flag,1,sizeof(flag));
scanf("%d",&n);
for(int i = 0; i < n; i++)
scanf("%d",&c[i]);
for(int i = 0; i < n; i++)
num[c[i]-1] = i+1;
int k = n,l = 1;
for(int i = 0; i < n; i++)
{
int o = 0;
for(int j = l; ; j++)
{
if(j > n)
j -= n;
if(flag[j])
o++;
if(j == num[i])
break;
}
a[i] = o;
flag[num[i]] = 0;
l = num[i];
m[i] = k--;
}
int m0,a0;
if(MLSE(m0,a0,n))
{
if(!a0)
printf("%d\n",a0+m0);
else
printf("%d\n",a0);
}
else
printf("Creation August is a SB!\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: