Mysterious Bacteria LightOJ - 1220
考察: 质数筛+分解质因数
但我觉得考察的应该是分情况处理的能力
- n>0,被唯一的质数分解 直接输出答案即可
- n>0,被多个质数分解(完全没想到还有这种数据) 输出的答案应该是最小的指数
- n<0,被唯一质数分解. 且指数为奇数. 这正好处理了负号问题,直接输出即可
- n<0,被唯一质数分解. 且指数为偶数.注意答案不一定是1.如-64 它可以由3个-4组成. 而不一定是-64.
- n<0,被多个质数分解.最小指数为奇数.正好输出.
- n<0,被多个质数分解,最小指数为偶数.说明答案必须除2直到==奇数
注意坑点:
- n不要声明ll 又用int读取,会导致n为正数
1 #include <iostream> 2 #include <algorithm> 3 #include <cmath> 4 #include <vector> 5 using namespace std; 6 typedef long long ll; 7 const int N = 1e6+10; 8 int prime[N],cnt; 9 bool st[N]; 10 vector<int> v; 11 void GetPrime(int n) 12 { 13 for(int i=2;i<=n;i++) 14 { 15 if(!st[i]) prime[++cnt] = i; 16 for(int j=1;prime[j]<=n/i;j++) 17 { 18 st[i*prime[j]] = 1; 19 if(i%prime[j]==0) break; 20 } 21 } 22 } 23 int GetDivide(ll n) 24 { 25 for(int i=1;prime[i]<=n/prime[i];i++) 26 { 27 if(n%prime[i]==0) 28 { 29 int s = 0; 30 while(n%prime[i]==0) n/=prime[i],s++; 31 v.push_back(s); 32 } 33 } 34 if(n>1) v.push_back(1); 35 sort(v.begin(),v.end()); 36 return v[0]; 37 } 38 int main() 39 { 40 // freopen("in.txt","r",stdin); 41 GetPrime(1e6); 42 int T,kcase = 0; 43 scanf("%d",&T); 44 while(T--) 45 { 46 v.clear(); 47 ll n,tmp; scanf("%lld",&n); 48 if(n<0) tmp = -n; 49 else tmp = n; 50 int ans = GetDivide(tmp); 51 while(n<0&&!(ans&1)) ans>>=1; 52 printf("Case %d: %d\n",++kcase,ans); 53 } 54 return 0; 55 }
补一个解法二,用唯一分解定理,对所有指数取gcd.注意负数指数必定为奇数.
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 using namespace std; 5 typedef pair<int,int> PII; 6 typedef long long LL; 7 const int N = 1e5+10; 8 int prime[N],cnt; 9 bool st[N]; 10 vector<PII> v; 11 void GetPrime(int n) 12 { 13 for(int i=2;i<=n;i++) 14 { 15 if(!st[i]) prime[++cnt] = i; 16 for(int j=1;prime[j]<=n/i;j++) 17 { 18 st[i*prime[j]] = 1; 19 if(i%prime[j]==0) break; 20 } 21 } 22 } 23 void GetDivide(LL n) 24 { 25 for(int i=1;prime[i]<=n/prime[i];i++) 26 { 27 if(n%prime[i]==0) 28 { 29 int t = 0,p = prime[i]; 30 while(n%prime[i]==0) n/=p,t++; 31 v.push_back({p,t}); 32 } 33 } 34 if(n>1) v.push_back({n,1}); 35 } 36 int gcd(int a,int b) 37 { 38 return b?gcd(b,a%b):a; 39 } 40 int main() 41 { 42 int T,kcase =0; 43 scanf("%d",&T); 44 GetPrime(N-1); 45 while(T--) 46 { 47 int n,p =0; 48 scanf("%d",&n); 49 v.clear(); 50 GetDivide(abs(1ll*n)); 51 for(int i=0;i<v.size();i++) 52 p = gcd(v[i].second,p); 53 while(p&&n<0&&p%2==0) p/=2; 54 p = max(p,1); 55 printf("Case %d: %d\n",++kcase,p); 56 } 57 return 0; 58 }