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 "); else printf("%d %d ",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 "); else{ int b=l/a,g=gcd(a,b),t=1; while(g!=1){ t*=g; a/=g; g=gcd(a,b); } printf("%d ",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 ",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 ",++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: ",++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 ",p[i],e1[i],e2[i]); if(e1[i]>e2[i]){flag=1;printf("Impossible to divide ");break;} if(e2[i]!=0&&e1[i]!=0) k=min(k,e2[i]/e1[i]); } if(!flag) printf("%d ",k); } return 0; }