HDU 2429 Word Game

64 篇文章 0 订阅
54 篇文章 0 订阅
以下是baidu找的题解
以单词为点,能前后相连的单词之间连边,得到一个有向图,求长度为奇数且小于等于N的不同的S->T的路径数。设邻接矩阵为A,则可通过求A
+ A ^ 3 + ... + A ^ N求解。构造一个矩阵后可通过logN次矩阵乘求解。


以下是本人代码
2饕饕不绝31MS0K2438BC++2008-10-22 12:53:26

  1. /*
  2. 求和的时候稍微做了点优化
  3. */
  4. #include <iostream>
  5. #include <string>
  6. using namespace std;
  7. #define MAX_SIZE 30
  8. char w[MAX_SIZE][11],ttmp[11];
  9. int moudle,k,size;
  10. inline int fid(char* k){int i;for(i=0;i<size;i++)if(strcmp(k,w[i])==0)return i;return 0;}
  11. long long tmp;
  12. struct Mat
  13. {
  14.     short g[MAX_SIZE][2*MAX_SIZE];
  15.     Mat operator+(const Mat&a)
  16.         {
  17.             Mat temp;
  18.             int i,j;
  19.             for(i=0;i<size;i++)
  20.                 for(j=0;j<size;j++)
  21.                     temp.g[i][j]=(g[i][j]+a.g[i][j])%moudle;
  22.             return temp;
  23.         }
  24.     Mat operator*(const Mat&a)
  25.         {
  26.             int i,j,k;
  27.             Mat temp;
  28.             for(i=0;i<size;i++)
  29.                 for(j=0;j<size;j++)
  30.                 {
  31.                     tmp=0;
  32.                     for(k=0;k<size;k++)tmp+=g[i][k]*a.g[k][j];
  33.                     if(tmp>=moudle)tmp%=moudle;
  34.                     temp.g[i][j]=tmp;
  35.                 }
  36.                 for(i=0;i<size;i++)
  37.                 for(j=size;j<2*size;j++)
  38.                 {
  39.                     tmp=a.g[i][j];
  40.                     for(k=0;k<size;k++)tmp+=a.g[i][k]*g[k][j];
  41.                     if(tmp>=moudle)tmp%=moudle;
  42.                     temp.g[i][j]=tmp;
  43.                 }
  44.                 return temp;
  45.         }
  46. }A,Ans,TA;
  47. Mat mul(Mat a,Mat b)
  48. {
  49.     Mat ret;
  50.     int i,j,k;
  51.     for(i=0;i<size;i++)
  52.         for(j=0;j<size;j++)
  53.         {
  54.             for(k=tmp=0;k<size;k++)tmp+=a.g[i][k]*b.g[k][j];
  55.             if(tmp>=moudle)
  56.                 tmp%=moudle;
  57.             ret.g[i][j]=tmp;
  58.             ret.g[i][j+size]=a.g[i][j+size];
  59.         }
  60.     return ret;
  61. }
  62. inline Mat pow(Mat t, int k) {
  63.        Mat temp;
  64.        for(;k;k>>=1,t=t*t)
  65.            if(k&0x1){temp=t;break;}
  66.         for(k>>=1,t=t*t;k;k>>=1,t=t*t)
  67.             if(k&0x1)temp=temp*t;
  68.        return temp;
  69. }
  70. int main()
  71. {
  72.     int i,j,t,sid,eid;
  73.     moudle=10001;
  74.     scanf("%d",&t);
  75.     while(t--){
  76.     scanf("%d",&size);
  77.     for(i=0;i<size;i++)scanf("%s",w[i]);
  78.     scanf("%s",ttmp);sid=fid(ttmp);
  79.     scanf("%s",ttmp);eid=fid(ttmp);
  80.     scanf("%d",&k);
  81.     for(i=0;i<size;i++)for(j=0;j<size;j++)A.g[i][j]=(w[i][strlen(w[i])-1]==w[j][0]);
  82.     TA=A;
  83.     for(i=0;i<size;i++)for(j=size;j<2*size;j++)A.g[i][j]=(i==j-size);
  84.     A=mul(A,A);
  85.     Ans=pow(A,1+((k-2+(k&0x1))>>1));
  86.     for(i=0;i<size;i++)
  87.         for(j=0;j<size;j++)
  88.             Ans.g[i][j]=Ans.g[i][j+size];
  89.     Ans=mul(TA,Ans);
  90.     printf("%d/n",Ans.g[sid][eid]);
  91.     }
  92.     return 0;
  93. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值