Kiki & Little Kiki 2
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1894 Accepted Submission(s): 979
Change the state of light i (if it's on, turn off it; if it is not on, turn on it) at t+1 second (t >= 0), if the left of light i is on !!! Given the initiation state, please find all lights’ state after M second. (2<= n <= 100, 1<= M<= 10^8)
If the ith character of T is '1', it means the light i is on, otherwise the light is off.
题意:
给出 m (1 ~ 10 ^ 8),代表有 m 秒钟,后给出 n(1 ~ 100) 个灯的开关状态(环)。每一秒钟如果该灯的左边灯是 1 的话,则改变自身灯的状态,输出当过了 m 秒后灯的状态。
思路:
矩阵快速幂。设 a,b,c 三盏灯:
ai+1 = (ci + ai)% 2;
bi+1 = (ai + bi)% 2;
ci+1 = (bi + ci)% 2;所以可以得到矩阵:

vector 中的 size 函数导致了 TLE, 每次循环求长度浪费了不少的时间,在已知的长度下就可以不用求了。
AC:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
int len;
mat mul (mat a, mat b) {
mat c(len, vec(len));
for (int i = 0; i < len; ++i) {
for (int j = 0; j < len; ++j) {
for (int k = 0; k < len; ++k) {
c[i][j] = (a[i][k] * b[k][j] + c[i][j]) % 2;
}
}
}
return c;
}
mat pow (mat a, int n) {
mat b(len, vec(len));
for (int i = 0; i < len; ++i) {
b[i][i] = 1;
}
while (n > 0) {
if (n & 1) b = mul(b, a);
a = mul(a, a);
n >>= 1;
}
return b;
}
int main() {
int n;
char str[105];
while (~scanf("%d%s", &n, str)) {
len = strlen(str);
mat a(len, vec(len));
for (int i = 0; i < len; ++i) {
if (!i) a[i][i] = a[i][len - 1] = 1;
else a[i][i] = a[i][i - 1] = 1;
}
a = pow(a, n);
for (int i = 0; i < len; ++i) {
int res = 0;
for (int j = 0; j < len; ++j) {
res ^= (a[i][j] & (str[j] - '0'));
}
printf("%d", res);
}
printf("\n");
}
return 0;
}
本文介绍了一种使用矩阵快速幂解决环形灯状态变化的问题。通过给定初始状态和时间,利用矩阵运算预测灯经过特定时间后的状态。适用于大规模数据处理。
793

被折叠的 条评论
为什么被折叠?



