# Greedy# Number Theory# GCD# Iteration

a254 - 畢氏‧三角‧製造

🔗 前往 ZeroJudge 原題

題目描述

題目要求計算給定一組木棍長度,最多可以製造出多少個「最約畢氏三角」。最約畢氏三角的定義是三邊長為正整數,滿足 a^2 + b^2 = c^2,且 a 和 b 的最大公因數為 1。木棍只能用於構成三角形的 a 和 b 邊,且每根木棍最多只能使用一次。

解題思路

程式碼使用貪心策略來尋找滿足畢氏定理且互質的木棍組合。首先,計算每個木棍長度的平方,儲存在 b 陣列中。然後,使用兩層迴圈遍歷所有可能的木棍組合。對於每對木棍,檢查它們是否都未被使用,以及它們的長度是否互質(使用 GCD 函數計算最大公因數)。如果滿足這些條件,則計算它們的平方和,並檢查該和是否為完全平方數。如果是,則將計數器 ans 增加 1,並將這兩根木棍標記為已使用。最後,輸出 ans 的值。

複雜度分析

  • 時間複雜度: O(n^2 * sqrt(max_value)),其中 n 是木棍的數量,max_value 是木棍長度的最大值。兩層迴圈導致 O(n^2) 的複雜度,而計算平方根導致 O(sqrt(max_value)) 的複雜度。
  • 空間複雜度: O(n),用於儲存木棍長度和是否已使用的標記。

程式碼

#include <iostream>
#include <cmath>
using namespace std;
long long int a[201],b[201],n;
bool used[201];
int GCD(int a, int b) {
	int buffer;
	while (b)
		buffer = a, a = b, b = buffer % b;
	return a;
}
int main(){
	cin.sync_with_stdio(false); cin.tie(0);
	while(cin >> n){
		for(int i=0;i<n;++i){
			cin >> a[i];
			b[i]=a[i]*a[i];
			used[i]=0;
		}
		int ans=0;
		for(int i=0;i<n;++i){
			for(int j=i+1;j<n;++j){
				if(used[i]==0&&used[j]==0&&GCD(a[i],a[j])==1){
					long long int buffer=b[i]+b[j],sb=sqrt(buffer);
					if ((sb * sb) == buffer){
						++ans;
						used[i]=used[j]=1;
					}
				}
			}
		}
		cout << ans << "\n";
	}
}

Discussion