숫자가 n개 주어지고 이중 두개를 연결시켰을 때 k로 나누어떨어지게 하는 숫자쌍의 수를 구하는 문제다.



1. 숫자를 입력받은 후에 pow(10, i)를 곱하면서 %k한 것을 vector[i]에 저장한다. 입력은 10^9까지이므로 i는 10까지


2. 각각의 숫자를 다시 돌아보면서 자리수 rad를 계산해서 ((k - self%k)%k + target)%k == 0 인 target을 이분탐색으로 찾는다. 여러개 있을 수 있기 때문에 upper_bound, lower_bound를 찾아야 한다.


3. ub~lb에 자신도 있다면 1을 빼준다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
 
typedef long long ll;
ll n, k, ans;
ll a[200001];
ll po[11];
vector<ll> aa[11];
 
ll rad(ll x) {
    ll ans = 0;
    while (x) {
        ans++;
        x /= 10;
    }
    return ans;
}
 
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    po[0= 1;
    for (int i = 1; i < 11++i)
        po[i] = po[i - 1* 10;
    cin >> n >> k;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        ll mm = 1;
        for (int j = 0; j < 11++j) {
            aa[j].push_back(((mm%k)*(a[i]%k)) % k);
            mm *= 10;
        }
    }
    for (int i = 0; i < 11++i)
        sort(aa[i].begin(), aa[i].end());
    for (int i = 0; i < n; ++i) {
        ll r = rad(a[i]);
        ll t = (k - (a[i]%k))%k;
        ans += upper_bound(aa[r].begin(), aa[r].end(), t) - lower_bound(aa[r].begin(), aa[r].end(), t);
        if (t == ((a[i]%k) * (po[r]%k)) % k) 
            ans--;
    }
    cout << ans;
    return 0;
}
cs


'codeforces > #506 div3' 카테고리의 다른 글

F. Multicolored Markers  (0) 2018.08.29
C. Maximal Intersection  (0) 2018.08.29
B. Creating the Contest  (0) 2018.08.29
A. Many Equal Substrings  (0) 2018.08.29

+ Recent posts