HDOJ-2232 误打误撞..构造矩阵..

     其实我是在做HDOJ-2238 机器人的舞蹈II 的...构造好矩阵再用矩阵连乘得到结果..结果一直WA...后来发现了2232和2238的描述几乎一模一样..就往2232交..结果就AC了..很蛋疼啊...不清楚机器人相同和机器人不同到底有何区别...

     回到这题..关键就是构造矩阵...这里实际上就是要构造各个状之间态经过一次转移能转化的方式数..用搜索就能打出一个8*8的表了...这个矩阵做N次连乘..其s[0][0]就是所需结果(这里是默认 { 11    为矩阵的0行 )...应该好理解吧...为什么只有8种状态..可以将相互之间能通过旋转,对称得到的状态看成同一种状态..那么总的状态数就是8种了..

                              11 }

我的表是离线打的..其实表是秒出的..仅仅为了缩减代码量~~这道题和HDOJ2238的差别到底何在啊!!!??!!

 

Program:

#include<iostream>  
#include<string.h>  
#include<stdio.h>  
#include<map>  
#define N 8
using namespace std;  
const int M[N][N]=
{9,32,16,8,4,8,4,0,
8,32,15,7,5,9,4,1,
8,30,17,8,4,10,3,1,
8,28,16,9,4,12,2,2,
6,30,12,6,9,10,6,2,
6,27,15,9,5,14,3,2,
8,32,12,4,8,8,7,2,
0,24,12,12,8,16,6,3
};
struct node
{
      int s[N][N];
}h,temp,T,_2M[33];
node Matrix_Mul(node a,node b)
{
      int k,i,j;
      memset(temp.s,0,sizeof(temp));
      for (k=0;k<N;k++)
         for (i=0;i<N;i++)
            for (j=0;j<N;j++)
               temp.s[i][j]=(temp.s[i][j]+a.s[i][k]*b.s[k][j])%9937;
      return temp;
}
node getmatrix(node h,int l)
{
      int k,i,p;
      k=1;
      _2M[0]=h;
      for (p=1;p<=30;p++)
      {
             _2M[p]=Matrix_Mul(_2M[p-1],_2M[p-1]);
             k*=2;
             if (k>l) break;
      }
      memset(T.s,0,sizeof(T.s));
      for (i=0;i<N;i++) T.s[i][i]=1;
      while (l)
      {
             while (k>l)
             {
                   k/=2;
                   p--;
             }
             T=Matrix_Mul(T,_2M[p]); 
             l-=k;
      } 
      return T;
}
void Output_Matrix(node h)
{
      int i,j;
      for (i=0;i<N;i++)
      {
            for (j=0;j<N;j++) printf("%d ",h.s[i][j]);
            printf("\n");
      }
      printf("----------------\n");
}
int main()  
{  
      freopen("input.txt","r",stdin);
      freopen("output.txt","w",stdout);
      int i,j,n; 
      while (~scanf("%d",&n))
      {
            for (i=0;i<N;i++)
               for (j=0;j<N;j++) h.s[i][j]=M[i][j];    
            h=getmatrix(h,n);
            Output_Matrix(h);
            printf("%d\n",h.s[0][0]);      
      }
      return 0;  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值