Squarefree number HDU
Squarefree number
In mathematics, a squarefree number is one which is divisible by no perfect squares, except 1. For example, 10 is square-free but 18 is not, as it is divisible by 9 = 3^2. Now you need to determine whether an integer is squarefree or not.
Input
The first line contains an integer T indicating the number of test cases. For each test case, there is a single line contains an integer N. Technical Specification 1. 1 <= T <= 20 2. 2 <= N <= 10^18
Output
For each test case, output the case number first. Then output "Yes" if N is squarefree, "No" otherwise.
解題思路:
由於任何一個數都可以由素數的乘積形式表示。我們要判斷一個數n是否含有平方數因子,那麼,只需要依次嘗試1~n的所有素數prime[i] ,如果n%(prime[i]^2)==0說明這不是一個Squarefree number,相反,若找不到這樣的素數那麼就能說明n是一個Squarefree number!
可問題在於2 <= N <= 10^18 。。。就連打出素數表都會爆。但我們考慮到最差情況N = 10^18 ,那麼我們判斷N是不是Squarefree number需要找的是N = prime1 ^2 * prime2 ,這裡的假設最小素因子prime1,那麼prime1絕不會超過1e6(超過1e6總體上就會超出1e18)。 所以我們得到了解法:遍歷1~1e6的所有素數,如果n%(prime[i]^2)==0直接輸出"No",如果沒有找到,只需要再通過開平方驗證n是不是平方數即可。
AC程式碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e6+5; int prime[maxn]; int isprime[maxn]; int tot; void init() { memset(isprime,true,sizeof(isprime)); for(int i=3;i<maxn;i++) if(!i&1) isprime[i] = false; for(int i=3;i<sqrt(1.0*maxn);i++) { if(isprime[i]) for(int j=i*i;j<maxn;j+=i*2) { isprime[j] = false; } } tot=0; prime[tot++] = 2; for(int i=3;i<maxn;i+=2) { if(isprime[i]) prime[tot++]=i; } } int main(void) { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int T;cin>>T; init(); int cas=0; while(T--) { ll n;cin>>n; int flag = true; for(int i = 0;i<tot&&(ll)prime[i]*prime[i]<=n;i++) { if(!(n%((ll)prime[i]*prime[i]))) { flag = false; break; } if(!n%prime[i]) n/=prime[i]; } if(n==1) { cout<<"Yes"<<endl; continue; } ll sqn = sqrt(1.0*n); if(sqn*sqn==n) flag = false; cout<<"Case "<<++cas<<": "<<(flag?"Yes":"No")<<endl; } } /* Accepted time:31ms Mem:5.6MB Length:1066 C++ */