完全平方數

ltign發表於2024-03-09

一、題目描述

P8754 [藍橋杯 2021 省 AB2] 完全平方數

二、問題簡析

2.1 唯一分解定理

唯一分解定理:大於1的自然數都可以唯一地寫成素數的積

由該定理,一個大於 \(1\) 的自然數 \(b\) 可以表示為 \(b=a_1^{p_1}*a_2^{p_2}*...*a_n^{p_n}\) (\(a_1, a_2, ..., a_n\)素數\(p_1, p_2, ..., p_n\) 為對應的指數,即有 \(p_n\) 個該數)。該自然數 \(b\) 的平方為 \(b^2 = a_1^{2p_1}*a_2^{2p_2}*...*a_n^{2p_n}\),所有的指數都是偶數
我們可以得到,若一個自然數是完全平方數,則將該自然數寫出素數的積後,每個素數的指數一定是偶數。

因此,我們可以分解 \(n\),將指數不為偶數的素數相乘,就得到了 \(x\)

2.2 分解自然數

以下程式碼給出瞭如何將大於 \(1\) 的自然數分解為素數的積。

// 將整數n分解成若干個素數,除1和本身
map<int, int> factors(int n)
{
    map<int, int> ans;      // 分解n後,有ans[i]個i
    // n==1,特殊考慮
    if (n == 1)
    {
        ans[n] = 1;
        return ans;
    }
    // 1和本身總是因數,這裡忽略
    for (int i = 2; i * i <= n; i++)
    {
        // 可能有若干個i
        while (n % i == 0)
        {
            ans[i]++;       // 分解出一個i
            n /= i;
        }
    }
    if (n != 1)             // n==1,已經分解完了
        ans[n] += 1;
    return ans;
}

三、AC程式碼

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int quickin(void)
{
	int ret = 0;
	bool flag = false;
	char ch = getchar();
	while (ch < '0' || ch > '9')
	{
		if (ch == '-')    flag = true;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9' && ch != EOF)
	{
		ret = ret * 10 + ch - '0';
		ch = getchar();
	}
	if (flag)    ret = -ret;
	return ret;
}



int main()
{
	#ifdef LOCAL
	freopen("test.in", "r", stdin);
	#endif
	
	ll n, ans = 1;
	cin >> n;
	if (n == 1)
	{
		cout << 4 << endl;
		return 0;	
	}
	
	for (ll i = 2; i * i <= n; i++)
	{
		ll cnt = 0;
		while (n % i == 0)
		{
			cnt += 1;
			n /= i;	
		}
		if (cnt % 2 != 0)    ans *= i;
	}
	if (n != 1)    ans *= n;
	
	cout << ans << endl;
	
	return 0;
}

相關文章