HihoCoder 1839 数学

这题本质上是个暴力。
首先把输入数字的所有位数加在一起,我们把它称为total,要求的就是total*(1111…111)(n位)的最小质因数。如果直接暴力求值的话单是对于一个质数求total*(1111…111)%Mod就要n的复杂度,非常不划算,所以我们需要把问题转化一下。
通过观察,可以得到这个结论
如果total*(1111...111)(n个1)%Mod == 0; 那么(total * 10^n - total)%(9*Mod) == 0
那么我们求(total * 10^n - total)%(9*Mod)可以使用二分法,复杂度就会下去。
剩下的就先做一个质数筛,对范围内的所有质数依此去试就可以了。
因为我也不太清楚哪里的范围是可以控制的,就没有用int,全用longlong了,请见谅。

#include <iostream>
#include <math.h>
#include <iomanip>
#include <string>
#include <cstdio>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
#define N 4500005
#define ll long long
using namespace std;

ll total;
ll len;
bool rec[N];
ll Pow(ll a,ll b,ll Mod){
    if(b == 1){
        return a%Mod;
    }
    ll tmp = Pow(a,b/2,Mod);
    ll ans = tmp * tmp %Mod;
    if(b&1){
        ans = ans * a % Mod;
    }
    return ans;
}

bool check(ll i){
    if(total % i == 0){
        return 1;
    }
    if((Pow(10,len,9*i) - 1 + 9*i)%(9*i) == 0){
        return 1;
    }else
    {
        return 0;
    }
    
}



char s[N];
ll n;
int main() {
    ll i, j, k, x, y;
    for(i=2;i<N;i++){
        if(!rec[i]){
            for(j=i+i;j<N;j+=i){
                rec[j] = 1;
            }
        }
    }
    scanf("%s",s);
    len = strlen(s);
    total = 0;
    for(i=0;i<len;i++){
        total += s[i] - '0';
    }
    for(i=2;i<=N;i++){
        if(!rec[i] && check(i)){
            printf("%lld\n",i);
            break;
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值