zoukankan      html  css  js  c++  java
  • 数论知识之佩尔方程

    佩尔方程

    解决问题:

    一般解决中解的问题。在大多数的时候都不会给你这个式子,要有你自己来推成这个形式。

    一定要注意当n为平方数的时候无解

    解决方法:

    一般都要你推出最小解(可以用程序跑出来第一个),计为(x[1],y[1])。然后再用递推公式来求解

    佩尔方程求解:

    x^2 - n*y^2 = 1

    x[i+1] = x[1]*x[i] + n* y[1]*y[i]

    y[i+1] = x[1]*y[i] + y[1]*x[i]

    例题1:

    传送门

    找出最大的整数n(1 <= n <= N)和整数x以使它们满足

    输入项输入包含几个测试用例。每个测试用例包含一个整数N,1 <= N <= 10 ^ 18。输入以N = 0结尾。输出量在每种情况的一行中,输出您找到的两个整数n和x。样本输入

    1
    2
    0

    样本输出

    1 1
    1 1

    #include<iostream>
    #include<algorithm>
    #include<vector> 
    using namespace std; 
    typedef long long ll;
    typedef __int128 hll;
    const int maxn=1e4+100;
    vector<ll> v;
    ll ans[maxn];
    ll n;
    //x^2==(n+1)*(2*n+1)/6
    //(4+3)^2-48x^2=1
    //先找到一个x,n
    //然后再用跌代公式做
    
    //x^2 - n*y^2 = 1
    //x[i+1] = x[1]*x[i] + n* y[1]*y[i]
    //y[i+1] = x[1]*y[i] + y[1]*x[i]
     
    int main(){
        hll x=7,y=1;
        while((x-3)/4<=1e18){
            if((x-3)%4==0){
                ans[v.size()]=y;
                v.push_back((x-3)/4);
            }
            hll x1=x,y1=y;
            x=7*x1+48*y1;
            y=7*y1+x1;
        } 
        while(scanf("%lld",&n)&&n){
            int p=upper_bound(v.begin(),v.end(),n)-v.begin()-1;
            printf("%lld %lld
    ",v[p],ans[p]);
        }
    } 











    例二:
    传送门
    如果三角形满足边长为连续的整数t-1,t,t + 1,并且面积为整数,则为Heron三角形。现在,对于给定的n,您需要找到与最小t
    大于或等于n的苍鹭三角形 
    输入项输入包含多个测试用例。多重输入的第一行是整数T(1≤T≤30000),后跟T行。每行包含一个整数N(1≤N≤10 ^ 30)。
    输出量对于每个测试用例,输出一行中最小的t。如果所需的苍鹭三角形不存在,则输出-1。样本输入
    4
    1
    2
    3
    4
    样本输出
    4
    4
    4
    4

    题意

    给定一个整数 N(1N1^30),求最小的整数 t,要求 tN,使得边长为 t1,t,t+1 的三角形面积为整数。

     

    #include<iostream>
    #include<algorithm>
    #include<vector> 
    using namespace std; 
    typedef long long ll;
    typedef __int128 hll;
    const int maxn=1e3+100;
    __int128 xx[maxn],yy[maxn]; 
    //x^2-3y^2=1 .
    /*
    x^2 - n*y^2 = 1
    x[i+1] = x[1]*x[i] + n* y[1]*y[i]
    y[i+1] = x[1]*y[i] + y[1]*x[i]
    */ 
    void read(__int128 &x) {//__int128的板子
        x = 0;
        char ch;
        int flag = 1;
        while (ch = getchar()) {
            if (ch == '-') flag = -1;
            if (ch >= '0' && ch <= '9') break;
        }
        x = ch-'0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            x = x*10 + ch-'0';
        }
        x *= flag;
    }
    
    
    void out(__int128 x) {
        if (x < 0) {
            x = -x;
            putchar('-');
        }
        if (x >= 10) out(x / 10);
        putchar(x % 10 +'0');
    }
    
    void inint(){
        xx[1]=2,yy[1]=1;
        for(int i=2;i<=100;i++){
            xx[i]=xx[i-1]*2+yy[i-1]*3;
            yy[i]=yy[i-1]*2+xx[i-1];
        }
    } 
    int main(){
        int t;
        cin>>t;
        inint();
        while(t--){
            __int128 n;
            read(n);
            for(int i=1;i<=100;i++){
                if(xx[i]*2>=n){
                    out(xx[i]*2);
                    cout<<endl;
                    break;
                }
            }
        }
        return 0;
    }
    
    







    根据海伦公式:S=p(pa)(pb)(pc)S=p(p−a)(p−b)(p−c)p=a+b+c2p=a+b+c2.

    代入,令 t2=xt2=x,化简得 S2=3x2(x21)S2=3x2(x2−1).

    题目要求 SS 为整数,则 (x21)(x2−1) 一定是3乘以一个平方数,

    即 x21=3y2x2−1=3y2,即 x23y2=1x2−3y2=1.

    易知最小解为(2, 1),用递推式求出其他解即可。

    由于题目 NN 的范围较大,到 1e30,可以使用 int128(1e38),本地测试1e38内,只有67个解。

     
  • 相关阅读:
    Scoop Windows 的命令行安装程序管理工具
    微信小程序:用 Promise 解决方案代替回调地狱。 修复 this._invokeMethod is not a function 的问题
    微信小程序 获取地理位置信息
    Vue 与 动态组件 import 的尝试
    exception: TypeError: Cannot read property '_modulesNamespaceMap' of undefined at getModuleByNamespac
    Vue 项目中断点没有跳转到指定源码的问题
    检查 chrome 插件是否存在
    vue-devtools 获取到 vuex store 和 Vue 实例的?
    HTML5的服务器EventSource(server-sent event)发送事件
    ps 渐进式图片的技巧(支持jpg,gif,png)
  • 原文地址:https://www.cnblogs.com/lipu123/p/13855503.html
Copyright © 2011-2022 走看看