首页 > 其他 > 详细

HDU-5668-Circle(中国余数定理/解同余方程组)

时间:2016-04-29 17:06:13      阅读:208      评论:0      收藏:0      [点我收藏+]

Circle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 320    Accepted Submission(s): 102


Problem Description
    技术分享Satiya August is in charge of souls.

    技术分享He finds n技术分享 souls,and lets them become a circle.He ordered them to play Joseph Games.The souls will count off from the soul1技术分享.The soul who is numbered k技术分享 will be taken out,and will not join in the game again.

    技术分享Now Satiya August has got the sequence in the Out Ordered,and ask you the smallest k技术分享.If you cannot give him a correct answer,he will kill you!
 

Input
    技术分享The first line has a number T,means testcase number.

    技术分享Each test,first line has a number n技术分享.

    技术分享The second line has n技术分享 numbers,which are the sequence in the Out Ordered**(The person who is out at ai技术分享th技术分享技术分享 round was numbered i技术分享)**.

    技术分享The sequence input must be a permutation from 1技术分享 to n技术分享.

    1T10,2n20技术分享.
 

Output
    技术分享For each case,If there is a eligible number k技术分享,output the smallest k技术分享,otherwise,output”Creation August is a SB!”.
 

Sample Input
1 7 7 6 5 4 3 2 1
 

Sample Output
420
 

Source

 

考虑对给定的出圈序列进行一次模拟,对于出圈的人我们显然可以由位置,编号等关系得到一个同余方程 一圈做下来我们就得到了n个同余方程 对每个方程用扩展欧几里得求解,最后找到最小可行解就是答案. 当然不要忘了判无解的情况.


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <stack>
using namespace std;
const int MAXN = 107;
int num[MAXN];
long long mod[MAXN],b[MAXN];  // k(%mod)==b
bool vis[MAXN];
void egcd(long long a, long long b, long long &d, long long &x, long long &y)
{
    if (!b)d=a,x=1,y=0;
    else
    {
        egcd(b, a%b, d, y, x);
        y -= x*(a / b);
    }
}
long long CRT(int n)
{
    long long M=mod[1],B=b[1],x,y,d;
    for (int i=2; i<=n; i++)
    {
        egcd(M,mod[i],d,x,y);
        if ((b[i]-B)%d)return -1;
        x=(b[i]-B)/d*x%(mod[i]/d);
        B+=x*M;
        M=M/d*mod[i];
        B%=M;
    }
    return (B+M)%M?(B+M)%M:M;
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n,p;
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        for(int i=1; i<=n; ++i)
        {
            scanf("%d",&p);
            num[p]=i;
        }
        int j=1,k;
        for(int i=1; i<=n; ++i)
        {
            k=1;
            while(j!=num[i])
            {
                if(!vis[j])++k;
                j=j%n+1;
            }
            vis[num[i]]=1;
            mod[i]=n-i+1;
            b[i]=k%mod[i];
        }
        int flag=CRT(n);
        if(flag==-1)cout<<"Creation August is a SB!\n";
        else cout<<flag<<endl;
    }
    return 0;
}






HDU-5668-Circle(中国余数定理/解同余方程组)

原文:http://blog.csdn.net/qq978874169/article/details/51253717

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!