UVA数学入门训练Round1[6]

Posted Candy?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA数学入门训练Round1[6]相关的知识,希望对你有一定的参考价值。

UVA - 11388

题意:输入g和l,找到a和b,gcd(a,b)=g,lacm(a,b)=l,a<b且a最小


 

g不能整除l时无解,否则一定g,l最小

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
int T,g,l;
int main(int argc, const char * argv[]){
    T=read();
    while(T--){
        g=read();l=read();
        if(l%g) printf("-1\n");
        else printf("%d %d\n",g,l);
    }
    return 0;
}

PS:Luogup1029求数量的话可以依据a*b=g*l枚举

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
ll g,l;
int cnt=0;
inline int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int main(int argc, const char * argv[]) {
    g=read();l=read();
    ll n=g*l;
    for(ll i=g;i<=l;i++){
        if(n%i) continue;
        ll j=n/i;
        if(gcd(i,j)==g) cnt++;
    }
    printf("%d",cnt);
    return 0;
}



UVA - 11889

题意:输入A和C,求最小的B使lcm(A,B)=C


用唯一分解定理想

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
int a,l,T;
inline int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int main(int argc, const char * argv[]) {
    T=read();
    while(T--){
        a=read();l=read();
        if(l%a) printf("NO SOLUTION\n");
        else{
            int b=l/a,g=gcd(a,b),t=1;
            while(g!=1){
                t*=g;
                a/=g;
                g=gcd(a,b);
            }
            printf("%d\n",b*t);
        }
    }
    return 0;
}



UVA - 10943

题意:k个不超过n的非负整数加起来和为n有几种方案


 

完全背包

f[i][j]表示i个数加起来和为j

转移可以从O(n)变O(1)

可以是f[i-1][j]+0,也可以是f[i][j-1]+1

f[i][j]=(f[i-1][j]+f[i][j-1])%MOD;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=105,MOD=1e6;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
int n,m,f[N][N];
void dp(){
    for(int i=0;i<=100;i++) f[i][0]=1;
    for(int i=1;i<=100;i++)
        for(int j=1;j<=100;j++)
            f[i][j]=(f[i-1][j]+f[i][j-1])%MOD;
}
int main(int argc, const char * argv[]) {
    dp();
    while((n=read())){
        m=read();
        printf("%d\n",f[m][n]);
    }
    
    return 0;
}



UVA - 10791

 

 

题意:输入n,求至少两个正整数,使lcm=n


 

唯一分解定理分解后就是最优解,注意素数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
int n;
ll sol(int n){
    if(n==1) return 2;
    int cnt=0,m=sqrt(n)+1;
    ll ans=0;
    for(int i=2;i<=m&&n!=1;i++) if(n%i==0){
        cnt++;
        ll d=1;
        while(n%i==0) n/=i,d*=i;
        ans+=d;
    }
    if(n>1) cnt++,ans+=n;
    if(cnt==1) return ans+1;
    else return ans;
}
int main(int argc, const char * argv[]) {
    int cas=0;
    while(scanf("%d",&n)!=EOF&&n){
        printf("Case %d: %lld\n",++cas,sol(n));
    }
    return 0;
}



 

UVA - 10780

题意: 输入n和m,求最大的k使m^k整除n!


 

唯一分解定理裸

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1e4+5;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
int T,m,n,e1[N],e2[N],p[N],vis[N],cnt=0;
void era(int n){
    int m=sqrt(n)+1;
    for(int i=2;i<=m;i++) if(!vis[i])
        for(int j=i*i;j<=n;j+=i) vis[j]=1;
    for(int i=2;i<=n;i++) if(!vis[i]) p[++cnt]=i;
}
void divide(int n,int e[]){
    for(int i=1;i<=cnt&&n!=1;i++) if(n%p[i]==0){
        int d=0;
        while(n%p[i]==0) n/=p[i],d++;
        e[i]+=d;
    }
}
int main(int argc, const char * argv[]){
    era(10000);
    T=read();int cas=0;
    while(T--){
        printf("Case %d:\n",++cas);
        memset(e1,0,sizeof(e1));
        memset(e2,0,sizeof(e2));
        m=read();n=read();
        divide(m,e1);
        for(int i=1;i<=n;i++) divide(i,e2);
        int flag=0,k=100000,len=max(m,n);
        for(int i=1;i<=len;i++){//printf("%d  %d %d\n",p[i],e1[i],e2[i]);
            if(e1[i]>e2[i]){flag=1;printf("Impossible to divide\n");break;}
            if(e2[i]!=0&&e1[i]!=0) k=min(k,e2[i]/e1[i]);
        }
        if(!flag) printf("%d\n",k);
    }
    
    return 0;
}

 

 

以上是关于UVA数学入门训练Round1[6]的主要内容,如果未能解决你的问题,请参考以下文章

●UVA 10674 Tangents

《训练指南》——6.7

《训练指南》——6.13

算法竞赛入门经典——训练指南

Cg入门6:函数2

比赛-6月Round1