sdnu 1255 Problem C. Boooooooo【pell方程】【高精度】

For given N, find the smallest pp,no smaller than N for which there exists an positive integer hh for which 

2hh(hh + 1) = pp(pp + 1)

数据范围 N (1 < N < 8*10¹⁸)

For each given N, output the smallest pp, If available pp does not exist, output -1

Sample Input

1
1

Sample Output

Case #1: 3

之前还在计蒜客遇到过:https://nanti.jisuanke.com/t/A1541
刚开始看错题意了/(ㄒoㄒ)/~~
推出了这么个东西


来源:
http://www.1728.org/puzzle2.htm
https://www.shyamsundergupta.com/triangle.htm
哭。
这玩意儿规律是3+2√2(3+根号8) 第n项是第n-1项的
3+2√2倍。
进入正题:

方法1:
枚举+杜教BM
到现在也不知道为啥错QAQ

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
    for(ll pp=1; pp<=100000; pp++)///枚举pp
    {
        for(ll hh=1; hh<=100000; hh++) ///寻找hh
        {
            if(hh*(hh+1)==2*pp*(pp+1))
            {
                cout<<hh*(hh+1)<<' '<<2*pp*(pp+1)<<' '<<hh<<endl;
                break;
            }
        }
    }
}

 然后扔进杜教BM

然后就凉了。。。
方法2:搜题解【正解】
pell方程+高精度
https://blog.csdn.net/icefox_zhx/article/details/79791325
https://www.cnblogs.com/LargeDumpling/p/9411066.html
顺手偷了一个高精度板子tql%%%开心+愉快
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 200
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,tst,tot=250;
char s[N];
struct bigint{
    int a[N],n;
    bigint(){memset(a,0,sizeof(a));n=0;}
     friend bigint operator+(bigint a,bigint b){
        bigint res;res.n=a.n;
        for(int i=1;i<=res.n;++i) res.a[i]=a.a[i]+b.a[i];
        for(int i=1;i<=res.n;++i) res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
        while(res.a[res.n+1]) res.n++,res.a[res.n+1]+=res.a[res.n]/10,res.a[res.n]%=10;
        return res;
    }friend bigint operator*(bigint a,int x){
        bigint res;res.n=a.n;
        for(int i=1;i<=res.n;++i) res.a[i]=a.a[i]*x;
        for(int i=1;i<=res.n;++i) res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
        while(res.a[res.n+1]) res.n++,res.a[res.n+1]+=res.a[res.n]/10,res.a[res.n]%=10;
        return res;
    }friend bigint operator-(bigint a,bigint b){
        bigint res;res.n=a.n;
        for(int i=1;i<=res.n;++i) res.a[i]=a.a[i]-b.a[i];
        for(int i=1;i<=res.n;++i) if(res.a[i]<0) res.a[i]+=10,res.a[i+1]--;
        while(!res.a[res.n]) --res.n;
        return res;
    }friend bigint operator/(bigint a,int x){
        bigint res;res.n=a.n;int tmp=0;
        for(int i=res.n;i>=1;--i){tmp=tmp*10+a.a[i];res.a[i]=tmp/x;tmp%=x;
        }while(!res.a[res.n]) --res.n;
        return res;
    }friend bool operator<(bigint a,bigint b){
        if(a.n<b.n) return 1;
        if(a.n>b.n) return 0;
        for(int i=a.n;i>=1;--i){
            if(a.a[i]<b.a[i]) return 1;
            if(a.a[i]>b.a[i]) return 0;
        }return 0;
    }
}a[310],b;
int main(){
//  freopen("data.in","r",stdin);
//  freopen("a.out","w",stdout);
    a[0].n=1;a[0].a[1]=1;a[1].n=1;a[1].a[1]=7;
    for(int i=2;i<=tot;++i) a[i]=a[i-1]*6-a[i-2];
    for(int i=1;i<=tot;++i) a[i]=a[i]/2;
    int T,kcase=0;
    scanf("%d",&T);
    getchar();
    while(T--){
        scanf("%s",s+1);
        cout<<"Case #"<<++kcase<<": ";
        n=strlen(s+1);b.n=n;
        for(int i=1;i<=n;++i) b.a[i]=s[n-i+1]-'0';
        for(int i=1;i<=tot;++i){
            if(a[i]<b) continue;
            for(int j=a[i].n;j>=1;--j) putchar(a[i].a[j]+'0');puts("");break;
        }
    }return 0;
}
posted @ 2019-08-13 21:05  观稳769  阅读(307)  评论(0编辑  收藏  举报