您的位置:首页 > 其它

POJ 1977 构造矩阵乘法

2012-04-01 15:04 330 查看
题目大意:

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

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

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

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

状态转移矩阵为:

     |111|

B=|001|

     |100|

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

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

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

这样就是规律了;

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

我们看看下面这个矩阵

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

           |GH|

到底代表什么意思呢?

我们可以这么看:

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

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

[b]这样1得到的票为A*E+B*G[/b]

可以发现当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张。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  matrix string list c