现在的位置: 首页 > 综合 > 正文

POJ 1977 构造矩阵乘法

2013年02月06日 ⁄ 综合 ⁄ 共 1772字 ⁄ 字号 评论关闭

题目大意:

有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张。

抱歉!评论已关闭.