Mysterious Bacteria LightOJ - 1220

原题链接

考察: 质数筛+分解质因数

但我觉得考察的应该是分情况处理的能力

  1. n>0,被唯一的质数分解 直接输出答案即可
  2. n>0,被多个质数分解(完全没想到还有这种数据) 输出的答案应该是最小的指数
  3. n<0,被唯一质数分解. 且指数为奇数. 这正好处理了负号问题,直接输出即可
  4. n<0,被唯一质数分解. 且指数为偶数.注意答案不一定是1.如-64 它可以由3个-4组成. 而不一定是-64.
  5. n<0,被多个质数分解.最小指数为奇数.正好输出.
  6. n<0,被多个质数分解,最小指数为偶数.说明答案必须除2直到==奇数

注意坑点:

  1.    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 }
View Code

 

posted @ 2021-01-26 23:45  acmloser  阅读(58)  评论(0编辑  收藏  举报