UVa 12169 (枚举+扩展欧几里得) Disgruntled Judge

时间:2021-11-06 05:46:40

题意:

给出四个数T, a, b, x1,按公式生成序列 xi = (a*xi-1 + b) % 10001 (2 ≤ i ≤ 2T)

给出T和奇数项xi,输出偶数项xi

分析:

最简单的办法就是直接枚举a、b,看看与输入是否相符。

 #include <cstdio>

 const int maxn =  + ;
const int M = ;
int T, x[maxn]; int main()
{
//freopen("12169in.txt", "r", stdin); scanf("%d", &T);
for(int i = ; i < *T; i += )
scanf("%d", &x[i]); bool ok;
for(int a = ; a < M; ++a)
{
for(int b = ; b < M; ++b)
{
ok = true;
for(int i = ; i <= *T; i += )
{
x[i] = (x[i-]*a + b) % M;
if(i < *T && x[i+] != (x[i]*a + b) % M)
{
ok = false;
break;
}
}
if(ok) break;
}
if(ok) break;
} for(int i = ; i <= *T; i += )
printf("%d\n", x[i]); return ;
}

代码君

第二种办法枚举a,根据x1、x3求b。

详见这里

 #include <cstdio>

 typedef long long LL;
const int maxn = + ;
const LL M = ;
int T;
LL x[maxn]; void gcd(LL a, LL b, LL& d, LL& x, LL& y)
{
if(!b) { d = a; x = ; y = ; }
else { gcd(b, a%b, d, y, x); y -= x*(a/b); }
} int main()
{
//freopen("12169in.txt", "r", stdin); scanf("%d", &T);
for(int i = ; i < *T; i += )
scanf("%lld", &x[i]); bool ok;
for(LL a = ; a < M; ++a)
{
LL t = x[] - a*a*x[];
LL g, k, b;
gcd(a+, M, g, b, k);
if(t % g != ) continue;
b *= t / g; ok = true;
for(int i = ; i <= *T; i += )
{
x[i] = (x[i-]*a+b) % M;
if(i < *T && x[i+] != (x[i]*a+b) % M)
{
ok = false;
break;
}
}
if(ok) break;
} for(int i = ; i <= *T; i += )
printf("%lld\n", x[i]); return ;
}

代码君