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;
}
2.1.3 HDU1713 相遇周期
好半天才理解了题意,原来就是求两个分数的最小公倍数.先通分(为了方便,直接用两个分母的积作为公倍数的分母),然后求分子的最小公倍数最为公倍数的分子,最后约分就可以了,如果分母是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;
}
2.1.6 HDU2504 又见GCD
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;
}