1. 程式人生 > >【xsy1116】數學題 奧數題

【xsy1116】數學題 奧數題

求解 要求 ali col 時間復雜度 奧數 不難 因數 while

真實奧數題

題目大意:給你正整數k$,r$。問你存在多少對$(x,y)$,滿足$x<y$且$x^2+y^2=kz^2$,並將所有符合條件的數對輸出。

數據範圍:$r≤1e9$,$k={1,2,3}$。

我們先考慮$k=1$的情況,顯然就是一個求勾股數對數的問。有一種經典的枚舉所有$x^2+y^2=z^2$且$(x,y,z)=1$的勾股數對數的式子:

$\begin{cases} x=2nm\\ y=n^2-m^2 \\ z=n^2+m^2 \end{cases}$

證明的話,展開下式子算算就好

我們只需要暴力枚舉r的因數進行計算就可以了,時間復雜度$O(r^{\frac{1.066}{\ln\ln\ n}+0.5})$(這個式子是抄來的,證明本蒟蒻不懂,反正是能過的qwq)。

慮$k=2$的情況,我們參考處理$k=1$的情況,列一組式子,可以枚舉所有$x^2+y^2=2z^2$且$(x,y,z)=1$的式子:

$\begin{cases} x=n-m\\ y=n+m \\ z=\sqrt{n^2+m^2} \end{cases}$

證明同上

我們不難發現,這時候求解的關鍵變為了求$z^2=n^2+m^2$的對數(並將所有方案打出),這不就是第一問嗎$qwq$。

我們只需要求出所有的$(n,m)$數對後,簡單轉化一波就可以了。

考慮k=3的情況,抱歉這個是無解的qwq

 1 #include<bits/stdc++.h>
 2
#define L long long 3 #define M 10000005 4 using namespace std; 5 6 pair<L,L> p[M]; int cnt=0; 7 8 int solve(L z,L bei){ 9 int res=0; 10 for(L n=1;n*n<=z;n++){ 11 L m=sqrt(z-n*n),x=0,y=0; 12 if(m*m+n*n!=z) continue; 13 x=2*n*m; 14 y=n*n-m*m;
15 if(x==y) continue; 16 if(x>y) swap(x,y); 17 if(x<=0) continue; 18 p[++cnt]=make_pair(x*bei,y*bei); 19 res++; 20 } 21 return res; 22 } 23 24 int main(){ 25 int cas; cin>>cas; 26 while(cas--){ 27 L k,z,ans=0; cin>>k>>z; cnt=0; 28 if(k==3) {printf("0\n"); continue;} 29 for(L i=1;i*i<=z;i++) if(z%i==0){ 30 ans+=solve(i,z/i); 31 if(i*i!=z) ans+=solve(z/i,i); 32 } 33 sort(p+1,p+cnt+1); 34 cnt=unique(p+1,p+cnt+1)-p-1; 35 if(k==2){ 36 for(int i=1;i<=cnt;i++){ 37 p[i]=make_pair(p[i].second-p[i].first,p[i].second+p[i].first); 38 } 39 sort(p+1,p+cnt+1); 40 cnt=unique(p+1,p+cnt+1)-p-1; 41 } 42 printf("%d\n",cnt); 43 for(int i=1;i<=cnt;i++) printf("%d %d\n",p[i].first,p[i].second); 44 45 } 46 }

【xsy1116】數學題 奧數題