srupのメモ帳

競プロで解いた問題や勉強したことを記録していくメモ帳

yukicoder No.6 使いものにならないハッシュ

問題

問題概要

省略

解法

ハッシュて書いてあるけど、特に知識などはいらず、ハッシュ生成の作業を実装するだけ。素数判定の部分にエラトステネスを使ってる。 またハッシュ生成後は1ケタの数字となるので、生成後の数字は多くても0~9の10通りに絞られるん。よって連続した素数の部分の最大のものを探す処理も簡単に書ける。

ミス

特になし。

コード

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
using namespace std;
#define rep(i,n) for(int i=0;i<(n);i++)

bool isprime[200000];
//エラトステネス
void eratos(int m){
    for (int i = 0; i <= m; ++i) isprime[i] = true;
    isprime[0] = isprime[1] = false;
    //iを残してiの倍数を消していく
    for (int i = 2; i <= m; ++i){
        if(isprime[i]){
            for (int j = 2 * i; j <= m; j += i){
                isprime[j] = false;
            }
        }
    }
    return;
}

int hashh(int num){
    while(num >= 10){
        int tmp = 0;
        while(num >= 10){
            tmp += num / 10;//1桁ずつ足していく
            num %= 10;
        }
        tmp += num;
        num = tmp;
    }
    return num;
}

int main(void){
    int k, n; cin >> k >> n;
    eratos(n);
    vector<pair<int, int> >   p;
    for (int i = k; i <= n; ++i){
        if(isprime[i]){
            p.push_back(make_pair(hashh(i), i));
        }
    }
    
    int ans = 0;
    int size = 0;
    int tmpa;
    for (int l = 0; l < p.size(); ++l){
        bool flag[10] = {false};
        int tmp = 0;//素数列の数を入れる
        tmpa = p[l].second;//元の素数列の最初の素数を入れておく
        for (int r = l; r < l + 10; ++r){
            if(r >= p.size()) break;

            if(flag[p[r].first] == false){
                tmp++; flag[p[r].first] = true;
            }else{
                break;
            }
        }

        if(tmp >= size){
            //答えの更新と、最大長さの更新
            ans = tmpa; size = tmp;
        }   
    }
    printf("%d\n", ans);
    return 0;
}