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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章