毕达哥拉斯三元组:poj 1305+佩尔方程:poj 1320,hdu 3292(特殊不定方程)

本文深入探讨了毕达哥拉斯三元组的概念及其性质,通过枚举法解决特定问题,并引入佩尔方程进行更复杂的应用。文章详细解释了解题思路和算法实现,提供了具体的代码实例,涵盖了Fermat vs Pythagoras、StreetNumbers和矩阵快速幂等经典问题。

毕达哥拉斯三元组:

正整数x,y,z构成一个本原毕达哥拉斯三元组且y为偶数,当且仅当存在互素的正整数m,n(m>n),其中m为奇数n为偶数,或者n为偶数m为奇数,并且满足:

                                                                                                             

poj 1305:Fermat vs. Pythagoras

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

解题思路:枚举m,n(1~sqrt(t)),找到满足定理条件的计数,然后将本原三元组乘以i(保证i*z在所给范围之内),得到的数用标记数组flag[]标记。

                                                                                                      

参考代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
int x,y,z,n,flag[maxn];
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
void solve(int t)
{
    int cnt=0;
    int temp=sqrt(t+0.0);
    memset(flag,0,sizeof(flag));
    for(int n=1;n<=temp;n++)
        for(int m=n+1;m<=temp;m++){
            if(m*m+n*n>t) break;
            if((n&1)!=(m&1)&&gcd(m,n)==1){
                cnt++;
                x=m*m-n*n;
                y=2*m*n;
                z=m*m+n*n;
                int i=1;
                while(i*z<=t){
                    flag[i*x]=flag[i*y]=flag[i*z]=1;
                    i++;
                }
            }
        }
    int count=0;for(int i=1;i<=t;i++) if(flag[i]==0) count++;
    cout<>n){
    solve(n);
   }
   return 0;
}

佩尔方程:  形如的不定方程。

通解(迭代公式):

                                           ,即

特解:暴力枚举或连分数法

                                                                         ,y++直到能被整除或带回原始佩尔方程成立

poj 1320 Street Numbers

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

解题思路: 1+2+…+n=(n+1)+…+m,即n(n+1)/2=(m-n)(m+n+1)/2,展开,(2m+1)^2-8n^2=1,令x=2m+1,y=n,x^2-8y^2=1这是典型的佩尔方程。

只要10组数据,枚举个特解x=3,y=1,拿递归公式求解即可。附代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
int main()
{
  // freopen("input.txt","r",stdin);
   int x1=3,y1=1,n,m,x,y;
   for(int i=0;i<10;i++){
    x=3*x1+8*y1;
    y=x1+3*y1;
    n=y;
    m=(x-1)/2;
    printf("%10d%10d\n",n,m);
    x1=x;
    y1=y;

   }
   return 0;
}


hdu 3292(矩阵快速幂+佩尔方程) No more tricks, Mr Nanguo

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3292

解题思路: 分析易得佩尔方程,x^2-ny^2=1,暴力枚举出特解,矩阵快速幂取模得到通项,进而得到答案。

参考代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
const int mod=8191;
int d,k;
struct matrix
{
    int m[2][2];
}a,p;
struct Matrix
{
    int m[2];
};
Matrix init()                         //暴力枚举求佩尔方程的特解
{
    Matrix c;
    int y=1;
    double temp=sqrt(d*y*y+1);
    while(floor(temp)!=ceil(temp)){
        y++;
        temp=sqrt(d*y*y+1);
    }
    c.m[0]=(int)temp%mod;c.m[1]=y%mod;
    a.m[0][0]=a.m[1][1]=int(temp)%mod;a.m[0][1]=(d*y)%mod;a.m[1][0]=y%mod;//a矩阵初始化
    return c;
}
Matrix Multi(matrix a,Matrix b)//2*2矩阵左×2*1矩阵
{
    Matrix c;
    for(int i=0;i<2;i++){
       c.m[i]=0;
       for(int j=0;j<2;j++)
         c.m[i]+=a.m[i][j]*b.m[j];
       c.m[i]%=mod;
    }
    return c;
}
matrix multi(matrix a,matrix b)//2*2矩阵×2*2矩阵,用于矩阵快速幂
{
    matrix c;
    for(int i=0;i<2;i++){
       for(int j=0;j<2;j++){
        c.m[i][j]=0;
       for(int k=0;k<2;k++)
         c.m[i][j]+=a.m[i][k]*b.m[k][j];
       c.m[i][j]%=mod;
       }
    }
    return c;
}
matrix quickpow_mod(matrix a,int b)
{
    matrix ans=p;
    while(b){
        if(b&1) ans=multi(ans,a);
        b>>=1;
        a=multi(a,a);
    }
    return ans;
}
int main()
{
  // freopen("input.txt","r",stdin);
   while(cin>>d>>k){
    p.m[0][0]=p.m[1][1]=1;p.m[0][1]=p.m[1][0]=0;
    double temp=sqrt(d);
    if(floor(temp)==ceil(temp)) cout<<"No answers can meet such conditions"<









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值