hdu 2276 Kiki & Little Kiki 2ti

44 篇文章 0 订阅
29 篇文章 0 订阅

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

本题我觉挺好的,思路很好!

题意:给你一排灯泡,如果该灯泡的左边是亮着的,那么该灯泡就要改变状态,否则状态保持不变!其中a1的左边是an.

该题的思想好就好在转为矩阵来模拟操作,m分钟,就相当于m个操作,就相当于作用于矩阵A上m次,即:A^m;

A是类似于:


这种形式,a * A^m 就为最终状态,其中a为每个给定灯泡状态的序列!用数据一模拟一下,的确很妙!

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int MAXN = 110;

struct Matrix
{
    int iMatrix[MAXN][MAXN];
};

Matrix iPer, iCell;
void Inite(int n)
{
    int i, j;
    memset(iPer.iMatrix, 0, sizeof(iPer.iMatrix));
    memset(iCell.iMatrix, 0, sizeof(iCell.iMatrix));
    for(i = 0; i < n; ++i)
        iPer.iMatrix[i][i] = 1;
    for(i = 0; i < n; ++i)
        for(j = 0; j < n; ++j)
            if(i == j)
                iCell.iMatrix[i][j] = iCell.iMatrix[i][j+1] = 1;
    iCell.iMatrix[n-1][0] = 1;
}

Matrix Multi_Matrix(Matrix a, Matrix b, int n)
{
    Matrix c;
    int i, j, k;
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
        {
            c.iMatrix[i][j] = 0;
            for(k = 0; k < n; ++k)
            {
                c.iMatrix[i][j] ^= (a.iMatrix[i][k] & b.iMatrix[k][j]);
            }
        }
    }
    return c;
}

Matrix Quick_Mod_Matrix(int k, int n)
{
    if(k == 1)
        return iCell;
    Matrix c, tmp;
    c = iPer, tmp = iCell;
    while(k)
    {
        if(k&1)
        {
            c = Multi_Matrix(c, tmp, n);
            k--;
        }
        k >>= 1;
        tmp = Multi_Matrix(tmp, tmp, n);
    }
    return c;
}

int main()
{
    int iOperNum, Len, i;
    char str[MAXN];
    Matrix res, c, tmp;
    while(~scanf("%d", &iOperNum))
    {
        scanf("%s", str);
        Len = strlen(str);
        Inite(Len);
        memset(tmp.iMatrix, 0, sizeof(tmp.iMatrix));
        for(i = 0; i < Len; ++i)
            tmp.iMatrix[0][i] = str[i] - '0';
        c = Quick_Mod_Matrix(iOperNum, Len);
        res = Multi_Matrix(tmp, c, Len);
        for(i = 0; i < Len; ++i)
            printf("%d", res.iMatrix[0][i]);
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值