標籤:
題目來源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=42
Background
Computer generated and assisted proofs and verification occupy a small niche in the realm of Computer Science. The first proof of the four-color problem was completed with the assistance of a computer program and current efforts in verification have succeeded in verifying the translation of high-level code down to the chip level.
This problem deals with computing quantities relating to part of Fermat‘s Last Theorem: that there are no integer solutions of for n > 2.
The Problem
Given a positive integer N, you are to write a program that computes two quantities regarding the solution of
where x, y, and z are constrained to be positive integers less than or equal to N. You are to compute the number of triples (x,y,z) such that x<y< z, and they are relatively prime, i.e., have no common divisor larger than 1. You are also to compute the number of values such that p is not part of any triple (not just relatively prime triples).
The Input
The input consists of a sequence of positive integers, one per line. Each integer in the input file will be less than or equal to 1,000,000. Input is terminated by end-of-file.
The Output
For each integer N in the input file print two integers separated by a space. The first integer is the number of relatively prime triples (such that each component of the triple is ). The second number is the number of positive integers that are not part of any triple whose components are all . There should be one output line for each input line.
Sample Input
1025100
Sample Output
1 44 916 27
解題思路:
這是一道數論題,用數學的語言描述就是:x, y, z∈N,給定一個數n,找出所有的x, y, z ≤ n,使得x2 + y2 = z2成立。如果要窮舉所有的x, y, z的話,按照題目所給的資料量,肯定是無法在限定時間內完成的。考慮利用畢達哥拉斯數的性質產生所有的x, y, z來解決,數學推導簡要介紹如下:
先假定x, y, z兩兩互質,由於x, y互質,故x, y中至少有1個是奇數。下面用反證法證明x和y中有且只有1個奇數。假定x, y都為奇數,設:
- x = 2a + 1
- y = 2b + 1
- x2 + y2 = (2a + 1)2 + (2b + 1)2
= 4(a2 + b2 + a + b) + 2
又因為x2和y2是奇數,則z2是偶數,且必能被4整除,與上式矛盾,因此x, y中只有一個奇數。
假設x為奇數,y為偶數,則z為奇數,2z與2x的最大公因數為2,2z和2x可分別寫作
- 2z = (z + x) + (z - x)
- 2x = (z + x) - (z - x)
那麼跟據最大公因數性質,z + x和z - x的最大公因數也為2,又因為:
- (z + x)(z - x) = y2,兩邊同除以4得:
((z + x) / 2)((z - x) / 2) = (y / 2)2
故可令:
- z + x = 2m2, z - x = 2n2
其中z = m + n, x = m - n(m與n互質)
則有:
- y2 = z2 - x2 = 2m22n2 = 4m2n2
即y = 2mn。
綜上所述,可得到下式:
- x = m2 - n2, y = 2mn, z = m2 + n2. (m, n為任意自然數)
這裡還有一個問題:題目要求統計(x, y, z)三元組的數量時只統計x,y和z兩兩互質的的情況,這個問題用上面的演算法就可以解決了。但對於統計p的數量,題目並不限定三元組是兩兩互質的。但是上式不能產生所有x, y, z並不是兩兩互質的情況。然而假設x與y最大公因數w不為1,則z也必能被w整除,因此w為x, y, z三個數的公因數。歸納總結可知,所有非兩兩互質的x0, y0, z0都可由一組互質的x, y, z乘以係數得到。根據以上理論就可以快速的求解了。
參考代碼:
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #define N 1000010 5 bool used[N]; 6 7 long long gcd(long long a , long long b) 8 { return b==0 ? a: gcd(b,a%b); } 9 10 int main()11 {12 long long n,a,b,c;13 long long count1,count2;14 while(scanf("%lld",&n)!=EOF)15 {16 count1=count2=0;17 memset(used,0,sizeof(used));18 long long m=(long long)sqrt(n+0.5);19 for(long long t=1; t<=m; t+=2)20 for(long long s=t+2; s*t<=n; s+=2)21 if(gcd(s,t)==1) //s>t>=1且s與t互質22 {23 a=s*t; //奇數24 b=(s*s-t*t)/2; //偶數25 c=(s*s+t*t)/2; //奇數26 if(c<=n) //在n範圍內的PPT27 {28 count1++;29 //printf("本原勾股數組:%lld %lld %lld\n",a,b,c);30 if(!used[a]) { count2++; used[a]=1; }31 if(!used[b]) { count2++; used[b]=1; }32 if(!used[c]) { count2++; used[c]=1; }33 34 for(int j=2; c*j<=n; j++) //j是倍數35 {36 if(!used[a*j]) { count2++; used[a*j]=1; }37 if(!used[b*j]) { count2++; used[b*j]=1; }38 if(!used[c*j]) { count2++; used[c*j]=1; }39 }40 }41 }42 printf("%lld %lld\n",count1,n-count2);43 }44 return 0;45 }
UVa 106 - Fermat vs Pythagoras(數論題目)