首页 > 试题广场 >

小红的完全平方数

[编程题]小红的完全平方数
  • 热度指数:220 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\,\,\,\,\,\,\,\,\,\,小红有一个长度为 n 的整数数组 \{a_1,a_2\dots,a_n\} ,如果从数组中任选两个数 a_i, a_j (i \neq j),他们的乘积都是完全平方数,那么这个数组就是好数组。
\,\,\,\,\,\,\,\,\,\,如果现在的数组不是一个好数组,小红可以执行任意多次操作:
\,\,\,\,\,\,\,\,\,\,\,\,\,\,\bullet\,从数组里选择一个数,将其乘以一个正整数 x ;
\,\,\,\,\,\,\,\,\,\,她想知道,最少需要多少次操作才能使数组变成好数组。

\,\,\,\,\,\,\,\,\,\,如果一个数可以被表示为一个整数的平方,那么这个数就是完全平方数

输入描述:
\,\,\,\,\,\,\,\,\,\,第一行输入一个整数 n\left(1 \leq n \leq 10^5\right) 代表数组中元素的数量。
\,\,\,\,\,\,\,\,\,\,第二行输入 n 个整数 a_1, a_2, \dots, a_n\left(1 \leq a_i \leq 10^6\right) 代表数组中的元素。


输出描述:
\,\,\,\,\,\,\,\,\,\,在一行上输出一个整数,代表最少需要的操作次数。
示例1

输入

4
1 1 4 2

输出

1

说明

\,\,\,\,\,\,\,\,\,\,将第四个数乘 2 即可,获得 [1, 1, 4, 4] ,其中任意两个数的和乘积为完全平方数。
示例2

输入

5
1 2 3 4 5

输出

3
1
发表于 2025-03-22 11:06:46 回复(3)
#include <bits/stdc++.h>
using namespace std;

const int MAXA = 1e6+5;

int spf[MAXA]; // 最小质因子表

// 线性筛求最小质因子
void sieve() {
    for (int i = 2; i < MAXA; ++i) spf[i] = 0;
    for (int i = 2; i < MAXA; ++i) {
        if (spf[i] == 0) {
            spf[i] = i;
            if ((long long)i * i < MAXA) {
                for (int j = i * i; j < MAXA; j += i) {
                    if (spf[j] == 0) spf[j] = i;
                }
            }
        }
    }
}

// 这里用vector存奇质因子,返回一个字符串方便哈希
string getOddPrimeSignature(int x) {
    unordered_map<int,int> cnt;
    while (x > 1) {
        int p = spf[x];
        cnt[p]++;
        x /= p;
    }
    vector<int> factors;
    for (auto &kv : cnt) {
        if (kv.second % 2 == 1) factors.push_back(kv.first);
    }
    sort(factors.begin(), factors.end());
    string res;
    for (int p : factors) res += to_string(p) + ",";
    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    sieve();

    int n; cin >> n;
    vector<int> a(n);
    for (int i=0; i<n; i++) cin >> a[i];

    unordered_map<string,int> freq;
    for (int x : a) {
        string sig = getOddPrimeSignature(x);
        freq[sig]++;
    }

    int maxFreq = 0;
    for (auto &kv : freq) {
        maxFreq = max(maxFreq, kv.second);
    }

    cout << n - maxFreq << "\n";

    return 0;
}

发表于 2025-06-01 11:33:15 回复(0)