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

毕达哥拉斯三元组:

正整数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"< 
           
          
         
       
     
     
    
    
   
   









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值