HDU_Steps2.1解题
2.1.1 HDU1108 最小公倍数 如题,a*b/gcd(a,b)即可
2.1.2 HDU2138 How Many Primes Numbers
直接判断会超时,直接打表空间不够,于是采用了部分打表,部分判断的方法.
似乎有一种随机素数测试的方法做这一题会更快一些,但没有上述方法简单
#include <cstdio> #include <string> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> #define MAXN 10000000 using namespace std; bool prime[MAXN]; int isp(int x){//判断 int k=(int)sqrt(x); for(int i=2;i<=k;i++)if(x%i==0)return 0; return 1; } void init(){//打表 prime[1]=1; for(int i=2;i<MAXN;i++){ if(prime[i])continue; for(int j=i*2;j<MAXN;j+=i){ prime[j]=1; } } } int main(){ int n,a; init(); while(scanf("%d",&n)!=EOF){ int r=0; while(n--){ scanf("%d",&a); if(a<MAXN)r+=(prime[a]?0:1); else r+=isp(a); } printf("%d\n",r); } //system("pause"); return 0; }
好半天才理解了题意,原来就是求两个分数的最小公倍数.先通分(为了方便,直接用两个分母的积作为公倍数的分母),然后求分子的最小公倍数最为公倍数的分子,最后约分就可以了,如果分母是1就输出整数
#include <cstdio> #include <string> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef __int64 LL; LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);} int main(){ int cas; LL fz1,fz2,fm1,fm2,fz,fm; scanf("%d",&cas); while(cas--){ scanf("%I64d/%I64d%I64d/%I64d",&fz1,&fm1,&fz2,&fm2); fz1*=fm2,fz2*=fm1; fm=fm1*fm2; LL fz=fz1/gcd(fz1,fz2)*fz2; LL gc2=gcd(fz,fm); fz/=gc2,fm/=gc2; if(fm!=1)printf("%I64d/%I64d\n",fz,fm); else printf("%I64d\n",fz/fm); } //system("pause"); return 0; }
2.1.4 HDU1722 Cake a+b-GCD(a,b) GCD(a,b)是重合的刀数的数量
2.1.5 HDU2136 Largest Prime Factor 求能整除该数的最大素数是第几个
素数筛法的灵活运用,后面的优先跟新,最后对应该数位置上存的数就是最大素数(第几个)了
#include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib> #include <string.h> using namespace std; int pri[1000001],n,ps; int main(){ memset(pri,0,sizeof pri); pri[1]=0,ps=0; for(int i=2;i<=1000000;i++){ if(pri[i])continue; ps++;//标记第几个素数 for(int j=i;j<=1000000;j+=i){ pri[j]=ps; } } while(scanf("%d",&n)!=EOF){ printf("%d\n",pri[n]); } return 0; }
a,c最大公约数是b,已知a,b求最小c,且b!=c
一开始以为就是2倍b,其实不对 因为这样a,c最大公约数可能就是c,而不是b,正确方法是从2*b开始枚举,依次加b,直到GCD(a,k*b)=b,则c=k*b
2.1.7 HDU1286 找新朋友,裸的欧拉函数,直接敲模板
2.1.8 HDU1717 小数化分数2 纯小数转分数
对有限小数 比如 0.53 直接 53/100 对于可约分的进行约分
对于循环小数,例如 0.(53) ==> 0.(53)*100=53.(53) ==> 53.(53)-0.(53)=53 ==>即(100-1)*0.(53)=53 ==>53/99
对于混循环 例0.3(53)==>0.3(53)*1000-0.3(53)*10=353.(53)-3.(53)=350 ==>即(1000-10)*0.3(53)=350=>350/990
#include <cstdio> #include <string> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; double gcd(double a,double b){return b==0?a:gcd(b,(int)a%(int)b);} int main(){ int cas; char line[20]; scanf("%d",&cas); while(cas--){ scanf("%s",line); double d1=0,d2=0,fz,fm;//无循环部分,循环部分,分子,分母 int ll=0,rl=0,pos;//无循环部分和循环部分的位数 for(pos=2;pos<strlen(line)&&line[pos]!='(';pos++)d1=d1*10+line[pos]-'0',ll++; for(pos++;pos<strlen(line)&&line[pos]!=')';pos++)d2=d2*10+line[pos]-'0',rl++; if(strchr(line,'(')-line>=0){//是循环小数时 fz=d1*pow(10,rl)+d2-d1; fm=pow(10,ll+rl)-pow(10,ll); }else{ fz=d1; fm=pow(10,ll); } LL gc=gcd(fz,fm); printf("%.0lf/%.0lf\n",fz/gc,fm/gc); } //system("pause"); return 0; }