hdu 2276 点灯(矩阵应用)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2276

题意:有n盏灯,0表示不亮,1表示亮,如果 i-th的灯的左边灯是亮的,那么下一秒钟,i-th灯的状态要改变,0变成1,1变成0。问你在第t秒时,灯的状态时什么样的,输出来。

于是有:

a1 = (a1+an)%2,a2 = (a1+a2)%2,a3 = (a2+a3)%2,……an = (an+an-1)%2

构造矩阵:

|1 0 0 0··· 0 0 1|   a1   |a1+an|   

|1 1 0 0··· 0 0 0|   a2   |a1+a2|

|0 1 1 0 ···0 0 0|   a3   |a2+a3|

|0 0 1 1 ···0 0 0|   a4   |a3+a4|

| ···                  |   ai    |……... |

|A|^M|B|=|E|;B为输入矩阵,即为| a1 a2 a3 a4 ... ai |

从而矩阵求幂即可;

但一开始我用递归求幂,发现栈溢出。。。。

然后把求幂函数改了就过了。。。。

View Code
 1 #include<iostream>
 2 #include<string>
 3 const int N=101;
 4 using namespace std;
 5 string str;
 6 int len,n;
 7 
 8 struct Matrix{
 9     int map[N][N];
10 };
11 
12 Matrix mata,matb,Unit;
13 
14 void Initiate(){
15     for(int i=0;i<len;i++){
16         for(int j=0;j<len;j++){
17             if(i==0&&(j==0||j==len-1)){
18                 if(i==j)Unit.map[i][j]=1;
19                 else Unit.map[i][j]=0;
20                 mata.map[i][j]=1;
21             }else{ 
22                 if(i==j)Unit.map[i][j]=1;
23                 else Unit.map[i][j]=0;
24                 mata.map[i][j]=0;
25             }
26         }
27     }
28     for(int i=1;i<len;i++){
29         mata.map[i][i]=mata.map[i][i-1]=1;
30     }
31     for(int i=0;i<len;i++){
32         matb.map[i][0]=str[i]-'0';
33     }
34 }
35 
36 Matrix Mul(Matrix &a,Matrix &b){
37     Matrix c;
38     for(int i=0;i<len;i++){
39         for(int j=0;j<len;j++){
40             c.map[i][j]=0;
41             for(int k=0;k<len;k++){
42                 c.map[i][j]^=a.map[i][k]&b.map[k][j];
43             }
44         }
45     }
46     return c;
47 }
48 /*
49 Matrix Pow(int n){
50     if(n==1)return mata;
51     else if(n&1){
52         return Mul(mata,Pow(n-1));
53     }else {
54         Matrix temp=Pow(n>>1);
55         return Mul(temp,temp);
56     }
57 }
58 */
59 
60 Matrix Pow(int n){
61     Matrix p=Unit,q=mata;
62     while(n){
63         if(n&1){
64             p=Mul(p,q);
65         }
66         n>>=1;
67         q=Mul(q,q);
68     }
69     p=Mul(p,matb);
70     return p;
71 }
72 
73 int main(){
74     while(scanf("%d",&n)!=EOF){
75         cin>>str;
76         len=str.size();
77         Initiate();
78         mata=Pow(n);
79         for(int i=0;i<len;i++){
80             printf("%d",mata.map[i][0]);
81         }
82         printf("\n");
83     }
84     return 0;
85 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值