唯一分解定理入门题 + UVA-10791 + UVA-10375+UVA-10622+CodeForces-1294C+计蒜客 - T2059

Minimum Sum LCM

Minimum Sum LCM
输入整数 n(1≤n≤2^31-1) , 求至少两个正整数,使得它们的公倍数最小为n,且这些整数的和最小。输出最小的和。

思路:设 n = p 1 c 1 p 2 c 2 p 3 c 3 p m c m {{n=p_1^{c_1}*p_2^{c_2}*p_3^{c_3}……} p_m^{c_m}}
那么答案就是
i = 1 m p i c i \sum_{i=1}^m p_i^{c_i}
注意点:
① n=2^31-1 ,小心溢出,
② n为素数时,应该是1、n这两个数,
③如果是1,答案应该是2。

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std;
int n,ncase=1;
int cnt;
ll ans;
void fenjie(int n){
    cnt=0;
    ll temp;
    ans=0;
    int k=sqrt(n+1);
    for(int i=2;i<=k;i++){
        if(n%i==0){
            temp=1;
            while(n%i==0){
                temp*=i;n/=i;
            }
            ans+=temp;
            cnt++;
        }
    }
    if(n>1){  // n本身是质数
        ans+=n;cnt++;
    }
}
int main(){
    while(cin>>n && n){
        if(n==1){
            printf("Case %d: %d\n",ncase++,2);
        }
        else{
            fenjie(n);
            if(cnt==1) ans++;  // 如果本身是质数的话,应该1和它本身
            printf("Case %d: %lld\n",ncase++,ans);
        }
    }
    return 0;
}

Choose and divide

Choose and divide
Description:
组合数公式 C(m,n)=m!/((m-n)! * n!) , 现在请你计算C(p,q) /C(r,s).
输出一行包含5位小数精度的实数。
C m n = m ! ( m n ) ! n ! C_m^n=\frac{m!}{(m-n)!*n!}
注意点:
①先打素数表,再运用唯一分解定理
②函数的模块化处理。

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e4+10;
int e[maxn];
int np=0,pr[maxn],v[maxn+20];
int gg(int n){
    for(int i=2;i<=n;i++){
        if(!v[i]) pr[++np]=i;//此时的i为某个质数
        for(int j=1;j<=np && i*pr[j]<=n;j++){
            v[i*pr[j]]=1; //用这个合数的最小质因子去筛掉这个合数
            if(i%pr[j]==0) break;
        }
    }
    return np;
}

void fenjie_n(int n,int d)
{
    for(int i=1;i<=np;i++)
    {
        while(n%pr[i]==0)
        {
            n/=pr[i];
            e[i]+=d;
        }
        if(n==1) break; //提前结束
    }
}

void fenjie_Nfac(int n,int d)
{
    for(int i=2;i<=n;i++)
        fenjie_n(i, d);
}

int p,q,r,s;
int main(){
    gg(maxn);
    while (~scanf("%d%d%d%d",&p,&q,&r,&s)) {
        ms0(e);
        fenjie_Nfac(p, 1);
        fenjie_Nfac(q, -1);
        fenjie_Nfac(p-q, -1);
        fenjie_Nfac(r, -1);
        fenjie_Nfac(s, 1);
        fenjie_Nfac(r-s, 1);
        double ans =1;
        for(int i=1;i<=np;i++)
        {
            ans*=pow(pr[i], e[i]);
        }
        printf("%.5lf\n",ans);
    }
    return 0;
}

Perfect P-th Powers

Perfect P-th Powers
Description:
Given an integer x you are to determine the largest p such that x is a perfect pth power.
注意点:The value of x will have magnitude at least 2 and be within the range of a (32-bit) int in C, C++, and Java.
x要正负分开讨论。

思路:
将x唯一分解,求各个指数的最大公约数。
如果x为负,求出的最大公约数应是奇数(是偶数,就除2)。

如何求多个数的最大公约数

// int a[];
int g = a[0];
for(int i=1;i<size;i++)
{
	g = gcd(g,a[1]);
}

AC代码

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std;
ll gcd(ll a,ll b){
    while (b) {
        ll temp=b;
        b=a%b;
        a=temp;
    }
    return a;
}
struct node{
    ll p,ci;
}a[100];
ll j;
void fenjie(ll n){
    j=0;
    ll k=sqrt(n)+1;
    for(ll i=2;i<=k;i++){
        if(n%i==0){
            a[j].p=i;
            while(n%i==0){
                a[j].ci++;n/=i;
            }
            j++;
        }
    }
    //防止 n 自己就是素数
    if(n>k){
        a[j].p=n;a[j].ci=1;j++;
    }
}
int main(){
    ll n;
    while(scanf("%lld",&n)==1 && n){
        memset(a,0,sizeof(a));
        if(n>0){
            fenjie(n);
            ll g = a[0].ci;
            for(ll i=1;i<j;i++){
                g = gcd(g, a[i].ci);
            }
        printf("%lld\n",g);
        }
        else{
            n=-n;
            fenjie(n);
            ll g = a[0].ci;
            for(ll i=1;i<j;i++){
                g = gcd(g, a[i].ci);
            }
            while((g&1)==0){
                g/=2;
            }
        printf("%lld\n",g);
        }
    }
    return 0;
}

Product of Three Numbers

Product of Three Numbers
Description:
将一个整数n分解为三个不相同的数a,b,c;
主要就是多种情况的分类讨论。

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std;
int t,n;
struct node{
    int p,ci;
}a[100];
int j;
void fenjie(int n){
    j=0;
    int k=sqrt(n)+1;
    for(int i=2;i<=k;i++){
        if(n%i==0){
            a[j].p=i;
            while(n%i==0){
                a[j].ci++;n/=i;
            }
            j++;
        }
    }
    //防止 n 自己就是素数
    if(n>k){
        a[j].p=n;a[j].ci=1;j++;
    }
}


int main(){
    cin>>t;
    while(t--){
        memset(a, 0, sizeof(a));
        scanf("%d",&n);
        fenjie(n);
        if(j>=3){

            printf("YES\n%d %d %d\n",a[0].p,a[1].p,n/a[0].p/a[1].p);
        }
         else if(j==1){
             if(a[0].ci>=6){
                 int x= a[0].p;
                 printf("YES\n%d %d %d\n",x,x*x,(int)pow(x, a[0].ci-3));
             }else{
                 printf("NO\n");
             }
         }else{
             if(a[0].ci+a[1].ci>=4){
                 printf("YES\n%d %d %d\n",a[0].p,a[1].p,n/a[0].p/a[1].p);
             }else{
                 printf("NO\n");
             }
         }
    }
    return 0;
}

细胞分裂

细胞分裂
S i n {{S_i^n}} 个细胞不可分割地平均分到M个试管中,其实就是要求s%M==0;

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#define ll long long
const int INF = (1<<30);
using namespace std;
int m1p[30000+5];
int m1c[30000+5];
int N,m1,m2,s;
int j;
void fenjie(int n){
    j=0;
    int k=sqrt(n)+1;
    for(int i=2;i<=k;i++){
        if(n%i==0){
            m1p[j]=i;
            while(n%i==0){
                m1c[j]++;n/=i;
            }
            j++;
        }
    }
    if(n>k){
        m1p[j]=n;m1c[j]=1;j++;
    }
}
int main(){
    cin>>N>>m1>>m2;
    if(m1==1) {cout<<0<<endl;return 0;}
    //将试管数 m1^m2 进行唯一分解
    fenjie(m1);
    for(int i=0;i<j;i++) m1c[i]*=m2;
    int ans = INF;
    while(N--){
        cin>>s;
        int mintime=0,i;
        //对M的所有质因子进行判断
        for(i=0;i<j;i++){
            if(s%m1p[i]!=0) break;
            int si=0;
            while(s%m1p[i]==0){
                si++;s/=m1p[i];
            }
            // 有点像n个人租船租几条的问题
            int t= m1c[i]%si==0?m1c[i]/si:m1c[i]/si+1;
            mintime= max(mintime,t);
        }
        if(i==j) ans=min(mintime,ans); // i==j 才说明s是合法的,这时才能更新ans(先max后min)
    }
    if(ans==INF) cout<<-1<<endl;
    else printf("%d\n",ans);
    return 0;
}
发布了67 篇原创文章 · 获赞 0 · 访问量 1532

猜你喜欢

转载自blog.csdn.net/qq_44846324/article/details/104465830