• POJ 2427 Smith's Problem Pell方程


    题目链接 :  http://poj.org/problem?id=2427

    PELL方程几个学习的网址: 

    http://mathworld.wolfram.com/PellEquation.html     wolfram的讲解

    http://hi.baidu.com/aekdycoin/item/a45f7c37850e5b9db80c03d1     AC神的博客 

    http://blog.csdn.net/acdreamers/article/details/8529686    acdreamer的博客  (从这里知道的思路...

    Pell方程 :  形如 X2 - D*Y2 = 1 的式子我们称作Pell方程 (D为正整数)

    Pell方程的推广形式 :  形如A*X- B*Y= C 的式子我们称作Pell方程的推广 (其中 A,B,C均为正整数)   

    本题是Pell方程的最小根

    按照Pell方程连分数解法的定义 , 只需要求出sqrt(N)的连分数即可 

    于是我苦翻了一天数论书看懂了连分数的性质...公式在初等数论及其应用 P370

    所以我们只需要一直求连分数sqrt(N)的 收敛子p/q p,q就是最后我们要求的答案

    但是这题不需要化成连分数的向量形式即 [a1;a2,a3...] , 因为double精度误差很大,BigDecimal很不方便 而且 找循环节很复杂

    这题只需要用下面的定理即可 ...本题中 P0 = 0,Q0 = 1  ,这里因为求出Pk,Qk会非常大 , 所以用Java的BigInteger实现更方便

    import java.util.*;
    import java.io.BufferedInputStream;
    import java.math.*;
    public class Main {
        public static void main(String[] args) {
            Scanner cin = new Scanner(new BufferedInputStream(System.in)); 
            while(cin.hasNext()){
                int n = cin.nextInt();
                double p = Math.sqrt(n);
                int k = (int)p;
                if(k == p) {
                    System.out.println("No solution!");
                    continue;
                }else {
                    /*
                     *  逐项求 sqrt(D) 的连分数 用p/q表示 
                     *  公式在初等数论及其应用P370
                     */
                    BigInteger x = BigInteger.ONE; //p
                    BigInteger y = BigInteger.ONE; //q 
                    BigInteger a,N,P1,Q1,P2,Q2,ak,p1,q1,p2,q2;
                    q1 = p2 = P1 = BigInteger.ZERO;
                    p1 = q2 = Q1 = BigInteger.ONE;
                    N = BigInteger.valueOf(n); // N = n;
                    a = BigInteger.valueOf(k); // a = [sqrt(n)]
                    ak = a; //ak
                    while(!x.multiply(x).subtract(N.multiply(y).multiply(y)).equals(BigInteger.ONE)){
                        x = ak.multiply(p1).add(p2); // p[k] = ak * p[k-1] + p[k-2]
                        y = ak.multiply(q1).add(q2); // q[k] = ak * q[k-1] + q[k-2]
                        P2 = ak.multiply(Q1).subtract(P1);  //P2=P[k+1];
                        Q2 = N.subtract(P2.multiply(P2)).divide(Q1); //Q2=Q[k+1];
                        ak = P2.add(a).divide(Q2); //ak 
                        
                        P1 = P2;  
                        Q1 = Q2;  
                        
                        p2 = p1; 
                        p1 = x; 
                        q2 = q1;
                        q1 = y;
                    }
                    System.out.println(x+" "+y);
                }
            }
        }
    }
  • 相关阅读:
    edu_2_4_1
    edu_2_3_2
    edu_2_3_1
    edu_2_2_2
    edu_2_1_1
    edu_2_2_1
    hdu 1270 小希的数表
    hdu 2151 worm
    hdu1089 Ignatius's puzzle
    hdu 2190 悼念512汶川大地震遇难同胞——重建希望小学
  • 原文地址:https://www.cnblogs.com/Felix-F/p/3222741.html
Copyright © 2020-2023  润新知