家庭作业(zadaca)

家庭作业(zadaca)

题目描述

Mirko最近收到了一个家庭作业,作业的任务是计算两个数A和B的最大公约数。由于这两个
数太大了,我们给出了N个数,他们的乘积是A,给出M个数,他们的乘积是B。
Mirko想要验算自己的答案,所以他想找你写一个程序来解决这个问题。如果这个最大公约
数超过了9位数,那么只需要输出最后9位就可以了。

输入

第一行包含一个正整数N,范围是1到1000。第二行是N个用空格隔开的正整数(小于10亿)
,他们的乘积是A。第三行包含一个正整数M,范围是1到1000。第四行是M个用空格隔开的
正整数(小于10亿),他们的乘积是B。

输出

输出有且只有一行,表示A和B的最大公约数,如果结果超过了9位数,输出最后9位数就
可以了。

在这里插入图片描述

分析:这道题一开始,我会想走高进度的方法的,可比赛完后听了其他巨佬的讲解,才发现自己好蒟!这里我提供两种思路,但是我只会讲第一种OK?

  1. 方法一:
    先输入第一个数组,不做处理,到输
    入第二个数组,每输入一个数跟第-一个
    数组每个数求最大公因数,和ans(ans初
    值为1)相乘,乘完之后两个数都要
    除以它们最大公因数,避免重复乘了,
    ans别忘了%1000000000。.
  2. 方法二:
    对于我们每次输入的数,我们都去分解质因数
    将它们用一个数组存起来并且用一个数组来记
    录每个质因数出现了多少次,最后判断两组数,
    也就是n个数,m个数,进行一遍暴力,判断同
    一个质因数,两个数那个少(注意不为零),
    因为我们要求最大公约数,那么最大也不会
    超过较小的那个,最后输出ans即可(记得
    考虑前导零)

code

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const long long mod=1000000000; 
long long n,m,t1[1005],t2[1005],ans=1;
long long ma(long long a,long long b){
	long long r;
	if(b>a){
		int t=a;a=b;b=t;
	}
	r=a%b;
	while(r){
		a=b;
		b=r;
		r=a%b;
	}
	return b;
}
int main(){
	bool f=false;
	freopen("zadaca.in","r",stdin);
	freopen("zadaca.out","w",stdout);
	scanf("%lld",&n);
	for(long long i=1;i<=n;++i){  //不做处理
		scanf("%lld",&t1[i]);
	}
	scanf("%lld",&m);
	for(long long i=1;i<=m;++i){
		scanf("%lld",&t2[i]);
		for(long long j=1;j<=n;++j){  //暴力做最大公约数
			long long e=ma(t2[i],t1[j]);
			ans=ans*e;  //将公约数乘入答案
			if(ans>mod){  //特判如何大于我们要取余的数,则要补前导零。
				ans%=mod;
				f=true;
			}
			t2[i]/=e;  //最后,两个数都要除于它两的最大公约数,避免重复再乘
			t1[j]/=e;
		}
	}
	if(!f)
		printf("%lld",ans);
	else 
		printf("%09lld",ans);
    fclose(stdin);
	fclose(stdout);
    return 0;
}

谢谢

发布了80 篇原创文章 · 获赞 58 · 访问量 2527

猜你喜欢

转载自blog.csdn.net/bigwinner888/article/details/104430539