题意:
基因题意:
N个基因 经过M次突变 A代表S1,B代表S2,
比如第一组数据,它的突变顺序就是S1,S2,S2,S1,S2,S2....我们要输出经过M次变异后的基因
接下来不是有两个N*N的东西吗,第一个就是代表S1,第二个代表S2,举个例子
(横着是i,竖着是j)
当i=0时,如何判断第i个基因是alive还是dead,就看相应的j了。j从0~n-1,位置(i,j)对应的值是1,且j位置对应的基因是alive的那么就s++,最终的s是奇数,i基因就是alive,否则就是dead,
以上就是一次变异
N个基因 经过M次突变 A代表S1,B代表S2,
比如第一组数据,它的突变顺序就是S1,S2,S2,S1,S2,S2....我们要输出经过M次变异后的基因
接下来不是有两个N*N的东西吗,第一个就是代表S1,第二个代表S2,举个例子
0 1 0 0 1 10 1 0
(横着是i,竖着是j)
当i=0时,如何判断第i个基因是alive还是dead,就看相应的j了。j从0~n-1,位置(i,j)对应的值是1,且j位置对应的基因是alive的那么就s++,最终的s是奇数,i基因就是alive,否则就是dead,
以上就是一次变异
(特别绕,有点晕)
解题思路:
输入原始基因,将它转化为数组pi[ ],alive为1,,dead为0
要求的表达式是 pi*s1...*s2*s1*...*s2*...(M个s1,s2) ===>有奇偶,对2取余
针对这个式子,我们可以先算出A个s1相乘,记为q1,再算出B个s2相乘,记为q2,
q3是q1*q2
求出M/(A+B)个q3的乘积
再将零碎的s1,s2乘起来,与pi相乘
最终的结果就是1代表alive,0代表dead
还有一点要注意的是s1,s2,横的变为竖的,看代码上的标记
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int n;
struct mat
{
int e[55][55];
};
mat mul(mat a, mat b)
{
mat ret;
memset(ret.e,0,sizeof(ret.e));
for(int i=0;i<n;i++)
for(int k=0;k<n;k++)
if(a.e[i][k])
for(int j=0;j<n;j++)
if(b.e[k][j])
ret.e[i][j] = (ret.e[i][j]+a.e[i][k]*b.e[k][j])%2;
return ret;
}
mat mpower(mat C,int m)
{
mat I;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
I.e[i][j] = (i==j);
while(m)
{
if(m&1) I = mul(I,C);
m>>=1;
C = mul(C,C);
}
return I;
}
int main()
{
int m,A,B;
while(cin>>n>>m>>A>>B)
{
mat a,b;
mat pi;
char s[10];
int t[5][55];
memset(t,0,sizeof(t));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>a.e[j][i];//把相应的位置变为一列一列的,否则会错 ,下面一样
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>b.e[j][i];
for(int i=0;i<n;i++)
{
scanf("%s",s);
if(s[0]=='a') pi.e[0][i]=1;
else pi.e[0][i]=0;
}
int tem = m/(A+B);
mat q1 = mpower(a,A);
mat q2 = mpower(b,B);
mat q3 = mul(q1,q2);
mat q4 = mpower(q3,tem);
mat q5 = mpower(a,min(m-tem*(A+B),A));
mat q6 = mpower(b,max(m-tem*(A+B)-A,0));
mat q7 = mul(q4,q5);
mat q8 = mul(q7,q6);
for(int i=0;i<1;i++)
for(int k=0;k<n;k++)
if(pi.e[i][k])
for(int j=0;j<n;j++)
if(q8.e[k][j])
t[i][j] = (t[i][j]+pi.e[i][k]*q8.e[k][j])%2;
for(int i=0;i<n-1;i++)
{
if(t[0][i]==1) cout<<"alive"<<" ";
else cout<<"dead"<<" ";
}
if(t[0][n-1]==1) cout<<"alive"<<endl;
else cout<<"dead"<<endl;
}
return 0;
}