【UVA】12169-Disgruntled Judge(暴力or欧几里得)

可能由于后台数据的原因,这道题直接暴力枚举a,b进行判断也能过,不过跑的时间长,效率太差了。

14021006 12169 Disgruntled Judge Accepted C++ 0.876 2014-08-11 08:46:28

不说了,比较无脑。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<list>
#include<string>
#include<sstream>
#include<ctime>
using namespace std;
#define _PI acos(-1.0)
#define INF 1 << 10
#define esp 1e-6
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pill;
/*===========================================
===========================================*/
#define MAXD 200 + 10
int main(){
    int T;
    int x[MAXD];
    scanf("%d",&T);
    for(int i = 1 ; i < 2 * T ; i+= 2)
        scanf("%d",&x[i]);
    int ok,a,b;
    for(a = 0 ; a <= 10000 ; a++){
        for(b = 0; b <= 10000 ; b++){
             ok = 1;
             for(int i = 2 ; i <= 2 * T ; i++){
                 if(i & 1){
                    if(x[i] != ((a * x[i - 1] + b) % 10001)){
                        ok = 0;
                        break;
                    }
                 }
                 else{
                    x[i] = (a * x[i - 1] + b) % 10001;
                 }
             }
             if(ok)
                break;
        }
        if(ok)
            break;
    }
    for(int i = 2 ; i <= 2 * T ; i+= 2)
    printf("%d\n",x[i]);
    return 0;
}

再一个办法就是枚举a,利用x1,x3求出b,判断所有x的关系能不能满足a,b。

如何通过a,x1,x3求出b呢。

x2 = (a * x1 + b) % 10001;

x3 = (a * x2 + b) % 10001;

联立2个式子

x3 = (a * (a * x1 + b) % 10001 + b ) % 10001;

x3 = (a * (a * x1 + b) + b) % 10001;

所以 x3 + 10001 * k = a * a * x1 + (a + 1) * b;

x3 - a * a * x1 = (a + 1) * b + 10001 * (-k);

这样就成了求 b 和 -k,满足这个式子,不就是扩展欧几里得的一般用法么?

14021484 12169 Disgruntled Judge Accepted C++ 0.012 2014-08-11 10:54:22

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<list>
#include<string>
#include<cmath>
#include<sstream>
#include<ctime>
using namespace std;
#define _PI acos(-1.0)
#define INF 1 << 10
#define esp 1e-6
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pill;
/*===========================================
===========================================*/
#define MAXD 200 + 10
#define max_size 10001
void gcd(LL a , LL b ,LL &d, LL &x,LL &y){
    if(!b){
        d = a ;
        x = 1;  y = 0;
        return ;
    }
    else{
        gcd(b , a % b ,d , y , x);
        y -= x * (a / b);
        return ;
    }
}
int main(){
    LL a,b,x[MAXD];
    int T;
    scanf("%d",&T);
    for(int i = 1 ; i < 2 * T  ; i += 2)
        scanf("%lld",&x[i]);
    for(a = 0; ; a++){
        LL k , b , d;
        LL t = (x[3] - a * a * x[1]);
        gcd(max_size, a + 1, d , k, b);
        if(t % d) continue;
        b = b * t / d;
        int yes = 1;
        for(int i = 2 ; i <= 2 * T ; i ++){
            if(i & 1){
                if(x[i] != ((a * x[i - 1] + b) % max_size)){
                     yes = 0;
                     break;
                }
            }
            else{
                x[i] = (a * x[i - 1] + b) % max_size;
            }
        }
        if(yes)
            break;
    }
    for(int i = 2 ; i <= 2 * T ; i+=2)
        printf("%lld\n",x[i]);
    return 0;
}

【UVA】12169-Disgruntled Judge(暴力or欧几里得),布布扣,bubuko.com

时间: 2024-11-24 13:09:35

【UVA】12169-Disgruntled Judge(暴力or欧几里得)的相关文章

UVA 12169 Disgruntled Judge 枚举+扩展欧几里得

题目大意:有3个整数 x[1], a, b 满足递推式x[i]=(a*x[i-1]+b)mod 10001.由这个递推式计算出了长度为2T的数列,现在要求输入x[1],x[3],......x[2T-1], 输出x[2],x[4]......x[2T]. T<=100,0<=x<=10000. 如果有多种可能的输出,任意输出一个结果即可. 由于a和b都小于等于10000,直接枚举a和b暴力可以过.但是有没有更快的方法呢? 首先令递推式的i=2,那么x[2]=(a*x[1]+b)mod 1

uva 12169 Disgruntled Judge

法一直接暴力枚举a和b的值,法二扩展欧几里德算法. #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <

UVA 12169 Disgruntled Judge【扩展欧几里德】

题意:随机选取x1,a,b,根据公式xi=(a*xi-1+b)%10001得到一个长度为2*n的序列,奇数项作为输入,求偶数项,若有多种,随机输出一组答案. 思路:a和b均未知,可以考虑枚举a和b,时间复杂度为10000*10000*100,但是题目数据比较水,这样枚举也是能过的.高效的做法是:枚举a,根据以下公式求出b. a*x1+b - MOD*y1 = x2; a*x2+b - MOD*y2 = x3; 解得: x3 - a*a*x1=(a+1)*b + MOD * y; 该方程为关于变量

hdu 2769 uva 12169 Disgruntled Judge 拓展欧几里德

//数据是有多水 连 10^10的枚举都能过 关于拓展欧几里德:大概就是x1=y2,y1=x2-[a/b]y2,按这个规律递归到gcd(a,0)的形式,此时公因数为a,方程也变为a*x+0*y=gcd(a,0)的形式,显然解为x=1,y=0,然后再递归回去就能得到解(a*x+b*y=gcd(a,b)的解) 1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm&g

uva 1426 - Discrete Square Roots(拓展欧几里得)

题目链接:uva 1426 - Discrete Square Roots 题目大意:给出X,N,R,求出所有满足的r,使得r2≡x%N,并且R是一个其中的解. 解题思路: R2?r2=k?N (R?r)(R+r)=k?N => aA=(R+r),bB=(R?r),A,B为N的因子 所以枚举A,B,就有r=R?aA=bB?R aA+bB=2?R 拓展欧几里得求解,将所有满足的解放入set中自动去重. #include <cstdio> #include <cstring> #

UVA 1347(POJ 2677)Tour(双调欧几里得旅行商问题)

Tour                 Time Limit:3000MS    Memory Limit:0KB    64bit IO Format:%lld & %llu Description John Doe, a skilled pilot, enjoys traveling. While on vacation, he rents a small plane and starts visiting beautiful places. To save money, John mus

12169 - Disgruntled Judge

枚举a和b...耗时0.126        显然这不是最好的方法,最好的方法是至需枚举a,利用扩展欧几里德算法求出线性模方程.求的b:其实我也还没有理解,等学会了再来更新.. #include<bits/stdc++.h> using namespace std; int T,a[109],b[109]; void solve() { for(int i=10000;i>=0;--i) for(int j=10000;j>=0;--j){ int kase=0; bool ok=

HDOJ 2769 Disgruntled Judge 扩展GCD

扩展GCD: 枚举a,扩展GCD求b,再暴力检查 Disgruntled Judge Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 329    Accepted Submission(s): 142 Problem Description Once upon a time, there was an nwerc judge with

uva 10413 - Crazy Savages(拓展欧几里得)

题目链接:uva 10413 - Crazy Savages 题目大意:一座山有m个山洞,形成一个圈,现在有n个部落的人,每个部落一开始住在ci山洞,第2天会向后面移动pi个位置,一共会在这座山住li天.现在如果两个部落在同一个山洞相遇,则会发生战争,问说m最小时多少的时候,保证不会发生争斗. 解题思路:因为每个部落都有自己的存在时间,所以枚举m,然后枚举两个部落,判断他们有没有可能相遇. 假设在第k天: ci+k?pi=a?m???(1) cj+k?pj=b?m???(2) 由(2)-(1)得