【牛客 - 280C】约数(数论,GCD,数学,分解因子)

题干:
 

Actci上课睡了一觉,下课屁颠屁颠的去找数学老师补课,问了老师一个题目:
    给出两个数a,b,问a和b的全部公约数是什么?
数学老师一看这道题太简单了,不屑回答,于是就交给了你。

输入描述:

一行两个数a,b.

输出描述:

a和b的全部公约数,每个数字之间空格隔开。

示例1

输入

复制

25 37

输出

复制

1

示例2

输入

复制

25 100

输出

复制

1 5 25

备注:

对于100%的数据,1 ≤ a,b ≤ 1013

解题报告:

   其实只需要先求出GCD来然后枚举GCD的因子就行了。

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
ll a,b;
ll ans[MAX];
int tot;
int main()
{
    cin>>a>>b;
    ll g = __gcd(a,b);
    for(ll i = 1; i*i<=g; i++) {
        if(g%i==0) ans[++tot] = i,ans[++tot] = g/i;
    }
    sort(ans+1,ans+tot+1);
    int x = unique(ans+1,ans+tot+1) - ans-1;
    for(int i = 1; i<=x; i++) {
        printf("%lld ",ans[i]);
        //if(i

附一个枚举因子的超时代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e6 + 5;
 
int aa[MAX],bb[MAX];
ll ans[MAX];
int cnta,cntb;
bool is(ll x) {
    for(ll i = 2; i*i<=x; i++) {
        if(x%i==0) return 0;
    }
    return 1 ;
}
void fenjie(ll x) {
    for(ll i = 2; i*i<=x; i++) {
        if(x%i == 0 && is(i)) {
            aa[++cnta] = i;
            while(x%i==0) x/=i;
        }
    }
    if(x>1) aa[++cnta]=x;
}
void fenjie2(ll x) {
    for(ll i = 2; i*i<=x; i++) {
        if(x%i == 0 && is(i)) {
            bb[++cntb] = i;
            while(x%i==0) x/=i;
        }
    }
    if(x>1) bb[++cntb]=x;
}
int main()
{
    ll a,b;
    int tot=0;
    cin>>a>>b;
    if(a > b) swap(a,b);
    fenjie(a);
    fenjie2(b);
    ans[++tot]=1;
    for(int i = 1; i<=cnta; i++) {
        if(binary_search(bb+1,bb+cntb+1,aa[i])==0) continue;
        ll yue = aa[i];
        for(int j = 1; j*yue<=a; j++) {
            if(b%(j*yue)==0&&a%(j*yue)==0) {
                ans[++tot] = j*yue;
                //printf(" %lld",j*yue);
            }
        }
    }
    sort(ans+1,ans+tot+1);
    int x = unique(ans+1,ans+tot+1) - ans - 1;
    for(int i = 1; i<=x; i++) {
        printf("%lld%c",ans[i],i == x ? '\n' : ' ');
    }
    return 0 ;
 }

 

你可能感兴趣的:(牛客网,数论,数学)