zoukankan      html  css  js  c++  java
  • 【[Offer收割]编程练习赛13 D】骑士游历(矩阵模板,乘法,加法,乘方)

    【题目链接】:http://hihocoder.com/problemset/problem/1504

    【题意】

    【题解】

    可以把二维的坐标转成成一维的;
    即(x,y)->(x-1)*8+y
    然后就写矩阵乘法吧。
    每个点每次能够到达的点是固定的;
    把每个点能够到达的点写成一个矩阵的形式;
    作为系数矩阵;
    求它的n次方
    然后初始矩阵a[(r,c)][(r,c)]=1
    用它去左乘系数矩阵;
    就能得到到每个点的方案数了;
    肯定都是不同的方案
    直接累计答案就好;
    最后注意是枚举到64而不是8了!!

    【Number Of WA

    0

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define ps push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    #define ref(x) scanf("%lf",&x)
    #define ms(x,y) memset(x,y,sizeof x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,-2,-1,1,2,2,1,-1,-2};
    const int dy[9] = {0,-1,-2,-2,-1,1,2,2,1};
    const double pi = acos(-1.0);
    const int N = 110;
    
    const int G = 64;       //矩阵大小
    const int MOD = 1e9 + 7;    //模数
    struct MX
    {
        int v[G+5][G+5];
        void O() { ms(v, 0); }
        void E() { ms(v, 0); for (int i = 1; i <= G; ++i)v[i][i] = 1; }
        void P()
        {
            for (int i = 1; i <= G; ++i)
            {
                for (int j = 1; j <= G; ++j)printf("%d ", v[i][j]); puts("");
            }
        }
        MX operator * (const MX &b) const
        {
            MX c; c.O();
            for (int k = 1; k <= G; ++k)
            {
                for (int i = 1; i <= G; ++i) if (v[i][k])
                {
                    for (int j = 1; j <= G; ++j)
                    {
                        c.v[i][j] = (c.v[i][j] + (LL)v[i][k] * b.v[k][j]) % MOD;
                    }
                }
            }
            return c;
        }
        MX operator + (const MX &b) const
        {
            MX c; c.O();
            for (int i = 1; i <= G; ++i)
            {
                for (int j = 1; j <= G; ++j)
                {
                    c.v[i][j] = (v[i][j] + b.v[i][j]) % MOD;
                }
            }
            return c;
        }
        MX operator ^ (LL p) const
        {
            MX y; y.E();
            MX x; memcpy(x.v, v, sizeof(v));
            int num[64+2],cnt = 0;
            while (p)
            {
                num[++cnt] = p&1;
                p>>=1;
            }
            for (int i =cnt;i>=1;i--)
            {
                y = y*y;
                if (num[i])
                    y = y*x;
            }
            return y;
        }
    }a,xishu;
    
    int change(int x,int y)
    {
        return (x-1)*8+y;
    }
    
    int n,r,c;
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        xishu.O();
        rep1(i,1,8)
            rep1(j,1,8)
            {
                rep1(k,1,8)
                {
                    int x = i+dx[k],y = j+dy[k];
                    if (x>=1 && x<=8 && y>=1 && y <=8)
                    {
                        xishu.v[change(i,j)][change(x,y)] = 1;
                    }
                }
            }
        rei(n),rei(r),rei(c);
        a.O();
        a.v[change(r,c)][change(r,c)] = 1;
        a = a*(xishu^n);
        int ans = 0;
        rep1(i,1,G)
            rep1(j,1,G)
            {
                ans = ans+a.v[i][j];
                if (ans>=MOD) ans-=MOD;
            }
        printf("%d
    ",ans);
        //printf("
    %.2lf sec 
    ", (double)clock() / CLOCKS_PER_SEC);
        return 0;
    }
    
  • 相关阅读:
    运维相关
    五指MUD协议
    android 超简单的拖动按钮 悬浮按钮 吸附按钮 浮动按钮
    find_player 不查找已经晕到玩家的问题
    练英语资源
    Java泛型
    JAVA WEB开放中的编码问题
    PHP初中高级学习在线文档下载
    springmvc请求参数获取的几种方法
    游戏数值——LOL篇 以LOL为起点-说游戏数值设计核心思路
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626461.html
Copyright © 2011-2022 走看看