HDU 3893 Drawing Pictures

/*
*  [题意]
*   有n个格子需要填色,有6种颜色(设为123456),要求:
*       1、填完后要对称
*       2、相邻不能同色
*       3、不可出现123456的情况
*  [解题方法]
*   由于是对称所以只要处理前(n+1)/2个,翻过去即可(注意此时不可出现654321,因为要翻过去)
*   即令n=(n+1)/2求解即可
*!设f(n,x):长度为n的以x结尾的合法颜色串个数
*   所以由题意得:
*       1、f(n,1) = f(n-1,2)+f(n-1,3)+f(n-1,4)+f(n-1,5)+f(n-1,6) - f(n-1,65432)
*       2、f(n,2) = f(n-1,1)+f(n-1,3)+f(n-1,4)+f(n-1,5)+f(n-1,6)
*       3、f(n,3) = f(n-1,1)+f(n-1,2)+f(n-1,4)+f(n-1,5)+f(n-1,6)
*       4、f(n,4) = f(n-1,1)+f(n-1,2)+f(n-1,3)+f(n-1,5)+f(n-1,6)
*       5、f(n,5) = f(n-1,1)+f(n-1,2)+f(n-1,3)+f(n-1,4)+f(n-1,6)
*       6、f(n,6) = f(n-1,1)+f(n-1,2)+f(n-1,3)+f(n-1,4)+f(n-1,5) - f(n-1,12345)
*
*       7、f(n,12) = f(n-1,1)
*       8、f(n,123) = f(n-1,12)
*       9、f(n,1234) = f(n-1,123)
*       10、f(n,12345) = f(n-1,1234)
*
*       11、f(n,65) = f(n-1,6)
*       12、f(n,654) = f(n-1,65)
*       13、f(n,6543) = f(n-1,654)
*       14、f(n,65432) = f(n-1,6543)
*
*   所以有矩阵:
*       |0 1 1 1 1 1 0 0 0 0  0 0 0 -1|       |f(n-1,1)     |       |f(n,1)     |
*       |1 0 1 1 1 1 0 0 0 0  0 0 0 0 |       |f(n-1,2)     |       |f(n,2)     |
*       |1 1 0 1 1 1 0 0 0 0  0 0 0 0 |       |f(n-1,3)     |       |f(n,3)     |
*       |1 1 1 0 1 1 0 0 0 0  0 0 0 0 |       |f(n-1,4)     |       |f(n,4)     |
*       |1 1 1 1 0 1 0 0 0 0  0 0 0 0 |       |f(n-1,5)     |       |f(n,5)     |
*       |1 1 1 1 1 0 0 0 0 -1 0 0 0 0 |       |f(n-1,6)     |       |f(n,6)     |
*       |1 0 0 0 0 0 0 0 0 0  0 0 0 0 |   *   |f(n-1,12)    |   =   |f(n,12)    |
*       |0 0 0 0 0 0 1 0 0 0  0 0 0 0 |       |f(n-1,123)   |       |f(n,123)   |
*       |0 0 0 0 0 0 0 1 0 0  0 0 0 0 |       |f(n-1,1234)  |       |f(n,1234)  |
*       |0 0 0 0 0 0 0 0 1 0  0 0 0 0 |       |f(n-1,12345) |       |f(n,12345) |
*       |0 0 0 0 0 1 0 0 0 0  0 0 0 0 |       |f(n-1,65)    |       |f(n,65)    |
*       |0 0 0 0 0 0 0 0 0 0  1 0 0 0 |       |f(n-1,654)   |       |f(n,654)   |
*       |0 0 0 0 0 0 0 0 0 0  0 1 0 0 |       |f(n-1,6543)  |       |f(n,6543)  |
*       |0 0 0 0 0 0 0 0 0 0  0 0 1 0 |       |f(n-1,65432) |       |f(n,65432) |
*   答案 = f(n,1) + f(n,2) + f(n,3) + f(n,4) + f(n,5) + f(n,6)
*/
#include 
#include 
#include 
using namespace std;
#define M 15
#define LL long long
#define FF(i, n) for(int i = 0; i < n; i++)

int ans[M], mod = 112233;
int ret[M][M], C[M][M];
int init[M][M];

void ini()
{
    memset(ans, 0, sizeof(ans));
    memset(init, 0, sizeof(init));
    FF(i, 6) {
        ans[i] = 1;
        FF(j, 6) if (i != j) init[i][j] = 1;
    }
    init[5][9] = -1;
    init[6][0] = init[7][6] = init[8][7] = init[9][8] = 1;
    init[0][13] = -1;
    init[10][5] = init[11][10] = init[12][11] = init[13][12] = 1;
}

void matmul(int a[][M], int b[][M], int n)
{
    int tp[M][M] = {0};
    FF(i, n) FF(k, n) if(a[i][k]) FF(j, n) if(b[k][j])
        tp[i][j] = (tp[i][j] + (LL)a[i][k]*b[k][j]) % mod;
    FF(i, n) FF(j, n) a[i][j] = tp[i][j];
}

void matmul(int a[], int b[][M], int n)
{
    int tp[M] = {0};
    FF(j, n) if(a[j]) FF(i, n) if(b[i][j])
        tp[i] = (tp[i] + (LL)b[i][j]*a[j]) % mod;
    FF(i, n) a[i] = tp[i];
}

void qmod(int n, int b)
{
    FF(i, n) FF(j, n) ret[i][j] = (i==j);
    for ( ; b; b >>= 1)
    {
        if (b & 1) matmul(ret, init, n);
        matmul(init, init, n);
    }
}

int main()
{
    int n;
    while (cin >> n)
    {
        if (n % 2 == 0) {
            puts("0");
            continue;
        }
        n /= 2;
        ++n;
        ini();
        qmod(14, n-1);
        matmul(ans, ret, 14);
        int sum = 0;
        FF(i, 6) sum = (sum + ans[i]) % mod;
        cout << (sum+mod)%mod << endl;
    }
    return 0;
}

 

你可能感兴趣的:(矩阵,C++,ACM,编程,算法,矩阵)