洛谷3518strongbox(poi2011)

本文探讨了一个数学问题,即如何找出给定密码及其相关因子中最小的有效因子,并通过编程实现了解决方案。文中详细介绍了如何利用最大公约数(GCD)和其他数学原理来确定哪些数可以作为密码使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意审题,a是密码,那么a,2a,3a……也是密码,推出t=gcd(n,ak)的倍数也是密码。这个t,可能是a+b=c中的c,也可能是其中的a,b。如果(a,b)是密码,那么存在ax+by=c,而这个方程有解的条件是c%gcd(a,b)==0,c的因子都可以是密码。

已知t是密码,t的因子也是密码,因此我们要找最小的因子。若a是密码,b不是密码,那么gcd(a,b)的因子也不是密码。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h> 
using namespace std;
const long long N=1e7+10;

long long gcd(long long a,long long b){
    if(b==0)return a;
    return gcd(b,a%b);
}
long long n,k,a[N]={0},b[N],gcdnk,tmp,j=0;
bool fb[N];//因子bi有没有被约掉 
int main(){

    int bj=0;
    cin>>n>>k;
    for(int i=1;i<=k;i++)scanf("%lld",&a[i]);
    gcdnk=gcd(n,a[k]);// 
    tmp=sqrt(gcdnk);
    for(int i=1;i<=tmp;i++)//求gcdnk的所有因子数;
        if(gcdnk%i==0)b[bj++]=i,b[bj++]=gcdnk/i; 
    if(b[bj-1]==b[bj-2])bj--; 
    sort(b,b+bj); 
    for(int i=1;i<k;i++)a[i]=gcd(a[i],gcdnk);
    long long ans=n;
    for(int i=1;i<k;i++){//找a[i] 在b[j]中是否出现过。 
        fb[lower_bound(b,b+bj,a[i])-b]=1;
    }
    for(int i=0;i<bj;i++){//去掉f[]=1的数的所有因子
        if(fb[i])
            for(int j=0;b[j]<b[i];j++) 
                if(b[i]%b[j]==0)fb[j]=1;
    }
    ans=1;
    for(int i=0;i<bj;i++)if(!fb[i]){ans=b[i]; break;}
    cout<<n/ans<<endl;	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值