zoukankan      html  css  js  c++  java
  • 洛谷P2579 [ZJOI2005]沼泽鳄鱼(矩阵快速幂,周期)

    例题:现在豆豆已经选好了两座石墩Start和End,他想从Start出发,经过K个单位时间后恰好站在石墩End上。假设石墩可以重复经过(包括Start和End),他想请你帮忙算算,这样的路线共有多少种(当然不能遭到食人鱼的攻击)。

    输入格式:第一行包含五个正整数N,M,Start,End和K,分别表示石墩数目、石桥数目、Start石墩和End石墩的编号和一条路线所需的单位时间。石墩用0到N–1的整数编号。

    第2到M + 1行,给出石桥的相关信息。每行两个整数x和y,0 ≤ x, y ≤ N–1,表示这座石桥连接着编号为x和y的两座石墩。

    第M + 2行是一个整数NFish,表示食人鱼的数目。

    第M + 3到M + 2 + NFish行,每行给出一条食人鱼的相关信息。每行的第一个整数是T,T = 2,3或4,表示食人鱼的运动周期。接下来有T个数,表示一个周期内食人鱼的行进路线。

    如果T=2,接下来有2个数P0和P1,食人鱼从P0到P1,从P1到P0,……;

    如果T=3,接下来有3个数P0,P1和P2,食人鱼从P0到P1,从P1到P2,从P2到P0,……;

     如果T=4,接下来有4个数P0,P1,P2和P3,食人鱼从P0到P1,从P1到P2,从P2到P3,从P3到P0,……。

    豆豆出发的时候所有食人鱼都在自己路线上的P0位置,请放心,这个位置不会是Start石墩。

    输出格式:输出路线的种数,因为这个数可能很大,你只要输出该数除以10000的余数就行了。

    #include<cstdio>
    #include<cstring>
    const int mod = 10000;
    
    int x,y,n,m,k,s,t,fish;
    int res[30][5],tt[30];
    
    struct Node{
        int a[60][60];
        Node operator *(const Node &x)const{
            Node ans;
            memset(ans.a,0,sizeof(a));
            for(int i = 0; i < n; ++i)
                for(int t = 0; t < n; ++t)
                    for(int k = 0; k < n; ++k)
                        ans.a[i][t] = (ans.a[i][t]+a[i][k]*x.a[k][t]) % mod;
            return ans;
        }
    }h[15],bb,base,ans;
    
    void quick_pow(int k){
        while(k){
            if(k&1)  ans = ans*base;
            base = base*base;  k >>= 1;
        }
    }
    
    int main(){
        scanf("%d%d%d%d%d",&n,&m,&s,&t,&k);
        for(int i = 1; i <= m; ++i){
            scanf("%d%d",&x,&y);
            bb.a[x][y] = bb.a[y][x] = 1;
        } 
        scanf("%d",&fish);
        for(int i = 0; i < fish; ++i){
            scanf("%d",&tt[i]);
            for(int t = 0; t < tt[i]; ++t)  scanf("%d",&res[i][t]);
        }
        for(int i = 0; i < 12; ++i){
            h[i] = bb;
            for(int t = 0; t < fish; ++t)
                for(int k = 0; k < n; ++k)  h[i].a[k][res[t][(i+1)%tt[t]]] = 0;   
        }
        base = h[0];
        for(int i = 1; i < 12; ++i)  base = base*h[i];
        for(int i = 0; i < n; ++i)  ans.a[i][i] = 1;
        quick_pow(k/12);    
        for(int i = 1; i <= k%12; ++i)    ans = ans*h[i-1];
        printf("%d",ans.a[s][t]);
        return 0;
    }
    你只有十分努力,才能看上去毫不费力。
  • 相关阅读:
    Jemter---基础概念
    Jmeter---线程操作
    性能接口面试题
    Linux---网络命令
    测试所用链接地址
    Linux---压缩解压命令
    Linux----用户管理命令
    性能面试题
    Linux---帮助命令
    Linux--文件搜索命令
  • 原文地址:https://www.cnblogs.com/214txdy/p/14024230.html
Copyright © 2011-2022 走看看