08-31 HDU_Steps2.1 HDU1108 HDU2138 HDU1713 HDU1722 HDU2136 HDU2504 HDU1286 HDU1717

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;
}



你可能感兴趣的:(08-31 HDU_Steps2.1 HDU1108 HDU2138 HDU1713 HDU1722 HDU2136 HDU2504 HDU1286 HDU1717)