当前位置: 代码迷 >> 综合 >> POJ 1977 构造矩阵乘法
  详细解决方案

POJ 1977 构造矩阵乘法

热度:0   发布时间:2024-01-20 20:32:13.0

题目大意:

有N个人,手上有Ai个标记,该人可以向指定的K个人添加标记(自己标记不会少)。

当该人手上有奇数个标记的时候,拥有投票权。问,最后有多少人手中的票为奇数个。

思路。以输入样例一为例:

初始状态矩阵:A=|210|

状态转移矩阵为:

     |111|

B=|001|

     |100|

于是乎第一轮结束后的状态:(A*B+A)

第二轮结束后的状态为:       (A*B+A)*B+(A*B+A)=> A*(B+E)*B+A*(B+E)=>A*(B+E)^2;

同样第三轮结束后:A*(B+E)^3

这样就是规律了;

另外还有注意的一点就是题中说当为奇数的时候有投票权,偶数没有投票权。

我们看看下面这个矩阵

|AB| * | EF |  = | A*E+B*G  A*F+B*H |

           |GH|

到底代表什么意思呢?

我们可以这么看:

1有A次投票机会,每次机会分别投给1E票,2G票。

2有B 次投票机会,每次机会分别投给1F票,2H票。

这样1得到的票为A*E+B*G

可以发现当ABEFGH中为偶数的时候,都是没有用的。

所以直接%2是正确的。再者利用了矩阵的结合律。这么分析完,敲敲就AC了。

发现我的代码可以rank10诶~哈哈

#include<iostream>
#include<string.h>
#include<map>
#define MAXN 222
using namespace std;typedef short ll;
struct node
{ll ma[MAXN][MAXN];void init(){memset(ma,0,sizeof(ma));}
}res,temp,L;
int allocp;
void init()
{allocp=0;res.init();temp.init();L.init();for( int i=0;i<MAXN;i++ )res.ma[i][i]=1;
}void set_Matrix()
{for( int i=0;i<allocp;i++ )temp.ma[i][i]++;
}node matriXmult( node a,node b )
{node c;memset( c.ma,0,sizeof(c.ma) );for( int i=0;i<allocp;i++ )for( int k=0;k<allocp;k++ )if( a.ma[i][k] )for( int j=0;j<allocp;j++ )c.ma[i][j]+=a.ma[i][k]*b.ma[k][j];for( int i=0;i<allocp;i++ )for( int j=0;j<allocp;j++ )c.ma[i][j]%=2;return c;
}void matrix_Power( int t )
{for( int i=0;i<31;i++ ){if( t&(1<<i) )res=matriXmult(res,temp);temp=matriXmult(temp,temp);}
}int main()
{int T,n,t,mark,list;string str1,str2;cin>>T;while( T-- ){init();map<string,int>map;map.clear();cin>>n>>t;while( n-- ){cin>>str1;if( map.find(str1)==map.end() )map[str1]=allocp++;cin>>mark>>list;L.ma[0][map[str1]]=mark;for( int i=0;i<list;i++ ){cin>>str2;if( map.find(str2)==map.end() )map[str2]=allocp++;temp.ma[map[str1]][map[str2]]++;}}t--;set_Matrix();matrix_Power(t);node kk;kk.init();for( int i=0;i<1;i++ )for( int j=0;j<allocp;j++ )for( int k=0;k<allocp;k++ )kk.ma[i][j]+=L.ma[i][k]*res.ma[k][j];int sum=0;for( int i=0;i<allocp;i++ )sum+=( kk.ma[0][i]%2 );cout<<sum<<endl;}return 0;
}



A有A张票,分别投给EE张,GG张。