LightOJ 1122

Given a set of digits S, and an integer n, you have to find how many n-digit integers are there, which contain digits that belong to S and the difference between any two adjacent digits is not more than two.

Input

Input starts with an integer T (≤ 300), denoting the number of test cases.

Each case contains two integers, m (1 ≤ m < 10) and n (1 ≤ n ≤ 10). The next line will contain m integers (from 1 to 9) separated by spaces. These integers form the set S as described above. These integers will be distinct and given in ascending order.

Output

For each case, print the case number and the number of valid n-digit integers in a single line.

Sample Input

3
3 2
1 3 6
3 2
1 2 3
3 3
1 4 6

Output for Sample Input

Case 1: 5
Case 2: 9
Case 3: 9

Note
For the first case the valid integers are

11
13
31
33
66

今天做hihoCoder碰到的一个题目,所用方法之前并不了解。所以,找了这题练练手

此题题解参考:http://www.cnblogs.com/aiterator/p/6685932.html

#include<bits/stdc++.h>
using namespace std;
 
typedef vector<unsigned int> vec;
typedef vector<vec> mat;
 
mat mul(mat &a, mat &b)
{
    mat c(a.size(), vec(b[0].size(), 0));
    for(int i=0; i<a.size(); ++ i)
    {
        for(int j=0; j<b[0].size(); ++ j)
        {
            for(int k=0; k<b.size(); ++ k)
                c[i][j] = c[i][j] + a[i][k] * b[k][j];
        }
    }
    return c;
}
 
mat pow(mat &a, unsigned int n)
{
    mat b(a.size(), vec(a[0].size(), 0));
    for(int i=0; i<a.size(); ++ i)
        b[i][i] = 1;
    while(n > 0)
    {
        if(n & 1)
            b = mul(b, a);
        a = mul(a, a);
        n >>= 1;
    }
    return b;
}
 
void solve(int cases)
{
    int m, n;
    cin >> m >> n;
    vec arr(m);
    for(int i=0; i<m; ++ i)
        cin >> arr[i];
    sort(arr.begin(), arr.end());
 
    mat a(m, vec(m, 0));
    for(int i=0; i<m; ++ i)
    {
        for(int j=max(0, i-2); j<min(m, i+3); ++ j)
        {
            if(abs(arr[i] - arr[j]) <= 2)
                a[i][j] = 1, a[j][i] = 1;
        }
    }
    mat b(1, vec(m, 1));
    mat c = pow(a, n-1);
    mat d = mul(b, c);
    unsigned int ans = 0;
    for(int i=0; i<d[0].size(); ++ i)
            ans += d[0][i];
    cout << "Case " << cases+1 << ": " << ans << endl;
}
 
int main()
{
    int t;
    cin >> t;
    for(int i=0; i<t; ++ i)
        solve(i);
    return 0;
}
原文地址:https://www.cnblogs.com/aiterator/p/6685972.html