该题题意很明显
第一思路很容易想到,直接枚举[1,n]的所有数x,看是否x与n相乘的数字开平方后的temp乘temp是否等于原来的数即可
#include<iostream> #include<cmath> #define int long long using namespace std; bool check(int n) { int temp = sqrt(n); if (temp * temp == n) { return true; } return false; } bool isPrime(int n) { int len = sqrt(n); for (int i = 2; i <= len; i++) { if (n % i == 0) { return false; } } return true; } signed main() { int n; cin >> n; if (isPrime(n)) { cout << n << endl; return 0; } for (int i = 1; i <= n; i++) { int temp = i * n; if (check(temp)) { cout << i << endl; break; } } return 0; } //1 4 9 16 25 36
但是因为题目的最大时间复杂度是10^12,所以该方法还无法AC
数论优化:
首先我们需要了解唯一分解定理。这个定理简单来说就是对于任意一个数 n,它都可以分解为若干个质数的乘积。 比如 60 就可以分解为 2^2 * 3 * 5
如果一个数是完全平方数,那么这若干个质数的指数都一定是偶数
比如,36=4*9=(2^2*3^2)
据此,我们只需要先对n进行质因数分解,然后补充进n的质因数的指数为奇数的哪些质因数即可
#include<iostream> #include<cmath> #define int long long #define MAX 1000 using namespace std; int index[MAX];//每个质因数的指数 int factor[MAX];//质因数 signed main() { int n, cnt = 0, ans = 1; cin >> n; int len = n; //先进行质因数分解 for (int i = 2; i*i <= len; i++) { if (n % i == 0) { cnt++; while (n%i==0) { factor[cnt] = i; index[cnt]++; n /= i; } } } if (n > 1) { factor[++cnt] = n; index[cnt]++; } for (int i = 1; i <= cnt; i++) { if (index[i] % 2) {//指数为奇数 ans *= factor[i]; } } cout << ans << endl; return 0; }