一、題目描述
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;
}
完