思路:
连分数求佩尔方程最小特解
模板:
LL a[20000]; bool min_pell(LL d, LL &x, LL &y) { LL m = floor(sqrt(d+0.5)); if(m*m == d) return false; int cnt = 0; a[cnt++] = m; LL b = m, c = 1; double sq = sqrt(d); do { c = (d - b*b)/c; a[cnt++] = (LL)floor((sq+b)/c); b = a[cnt-1]*c - b; }while(a[cnt-1] != 2*a[0]); LL p = 1, q = 0; for (int j = cnt-2; j >= 0; --j) { LL t = p; p = a[j]*p + q; q = t; } if(cnt%2) x = p, y = q; else x = 2*p*p+1, y = 2*p*q; return true; }
由于某些解超出long long范围,所以用到java大数
代码:
import java.math.*; import java.util.*; public class Main { public static long a[] = new long [200000]; public static BigInteger x, y; public static boolean min_pell(long d) { long m = (long)Math.floor(Math.sqrt(d+0.5)); if(m*m == d) return false; int cnt = 0; a[cnt++] = m; long b = m, c = 1; double sq = Math.sqrt(d); do { c = (d - b*b)/c; a[cnt++] = (long)Math.floor((sq+b)/c); b = a[cnt-1]*c - b; }while(a[cnt-1] != 2*a[0]); BigInteger p = BigInteger.ONE, q = BigInteger.ZERO; for (int j = cnt-2; j >= 0; --j) { BigInteger t = p; p = p.multiply(BigInteger.valueOf(a[j])).add(q); q = t; } if(cnt%2 != 0) { x = p; y = q; } else { x = p.multiply(p).multiply(BigInteger.valueOf(2)).add(BigInteger.ONE); y = p.multiply(q).multiply(BigInteger.valueOf(2)); } return true; } public static void main(String[] args) { // TODO Auto-generated method stub BigInteger mx = BigInteger.valueOf(0), ans = BigInteger.valueOf(5); for (long d = 1; d <= 1000; ++d) { if(!min_pell(d)) continue; //System.out.println(x); if(x.compareTo(mx) > 0) { mx = x; ans = BigInteger.valueOf(d); } } System.out.println(ans); } }