hdu5668Circle

来源:互联网 发布:懒人听书 源码 编辑:程序博客网 时间:2024/06/06 02:07

链接: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