• 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;
    }
    
  • 相关阅读:
    ACM进阶
    hdu 2018 母牛的故事
    hdu 2084 数塔
    动态规划算法
    hdu 1003 Max sum
    hihocoder 1037 数字三角形
    UDP和TCP的区别(转)
    JS简单的图片左右滚动
    C# MD5加密的方法+一般处理程序使用Session+后台Json序列化
    CSS DIV 独占一行,清除左右两边的浮动
  • 原文地址:https://www.cnblogs.com/aiterator/p/6685972.html
Copyright © 2020-2023  润新知