hdu5668Circle

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5668

题意:给定n个人的约瑟夫环的出队时间点,求出构造这个出队序列的最小报数k,如果无解输出"Creation August is a SB!"。

分析:看到题解说是模拟得出n个不定方程,然后用中国剩余定理求解。我想这个模拟想了半天,是不是像普通的数学方法求最后一个出队编号一样去做。然后这样想了很久,最后。。这TMn才20,直接手动模拟那个n^2的过程就是了啊!好蠢。然后就a了。。O(n^2)

代码:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=100010;
const int MAX=1000000100;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=998244353;
const int INF=1000000010;
typedef double db;
typedef unsigned long long ull;
void exgcd(ll a,ll b,ll &d,ll &x, ll &y) {
    if (!b) { d=a;x=1;y=0; }
    else { exgcd(b,a%b,d,y,x);y-=x*(a/b); }
}
int b[25],q[25];
ll a[25],m[25];
ll CRT1(int n,ll *a,ll *m) {
    ll M=1,d,y,z,x=0;
    for (int i=0;i<n;i++) M*=m[i];
    for (int i=0;i<n;i++) {
        z=M/m[i];
        exgcd(m[i],z,d,d,y);
        x=(x+y*z*a[i])%M;
    }
    return (x+M)%M;
}
ll CRT2(int n,ll *a,ll *m) {
    int i,bo=1;
    ll n1=m[1],n2,b1=a[1],b2,bb,d,t,k,x,y;
    for (i=2;i<=n;i++) {
        n2=m[i];b2=a[i];
        bb=b2-b1;exgcd(n1,n2,d,x,y);
        if (bb%d) {
            bo=0;break ;
        }
        k=bb/d*x;t=abs(n2/d);
        k=(k%t+t)%t;b1=b1+n1*k;n1=n1/d*n2;
    }
    if (!bo) return -1;
    if (b1<=0) b1+=n1;
    return b1;
}
int main()
{
    int i,j,n,t,x,w,tot,pre;
    ll ans;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        for (i=1;i<=n;i++) {
            scanf("%d", &x);b[x]=i;
        }
        w=tot=0;
        memset(q,0,sizeof(q));
        for (i=1;i<=n;i++) {
            for (pre=0,j=1;j<w;j++)
            if (!q[j]) pre++;
            while (1) {
                w=(w%n+n)%n+1;
                if (!q[w]) tot++;
                if (b[i]==w) break ;
            }
            a[i]=(ll)tot;m[i]=(ll)(n-i+1);
            q[w]=1;tot=0;
        }
        ans=CRT2(n,a,m);
        if (ans==-1) printf("Creation August is a SB!\n");
        else printf("%I64d\n", ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值