您的位置:首页 > 大数据 > 人工智能

POJ3735 Training little cats 矩阵快速幂

2018-03-17 19:02 477 查看
Training little cats
DescriptionFacer's pet cat just gave birth to a brood of little cats. Having considered the health of those lovely cats, Facer decides to make the cats to do some exercises. Facer has well designed a set of moves for his cats. He is now asking you to supervise the cats to do his exercises. Facer's great exercise for cats contains three different moves:
g i : Let the ith cat take a peanut.
e i : Let the ith cat eat all peanuts it have.
s i j : Let the ith cat and jth cat exchange their peanuts.
All the cats perform a sequence of these moves and must repeat it m times! Poor cats! Only Facer can come up with such embarrassing idea. 
You have to determine the final number of peanuts each cat have, and directly give them the exact quantity in order to save them.
InputThe input file consists of multiple test cases, ending with three zeroes "0 0 0". For each test case, three integers n, m and k are given firstly, where n is the number of cats and k is the length of the move sequence. The following k lines describe the sequence.
(m≤1,000,000,000, n≤100, k≤100)
OutputFor each test case, output n numbers in a single line, representing the numbers of peanuts the cats have.
Sample Input3 1 6
g 1
g 2
g 2
s 1 2
g 3
e 2
0 0 0Sample Output2 0 1
题意:有n只猫咪,开始时每只猫有花生米0颗,现给出k组操作,将该组操作做m(m<=10^9)次后,问每只猫咪有多少颗花生米。其中:
g i 表示第i只猫得到一个花生
e i 表示第i只猫吃掉所有花生

s i j 表示第i只猫和第j只猫交换花生。
分析:数据量大,采用矩阵快速幂。先构造单位矩阵,根据每组操作构造连乘矩阵,再做快速幂。(n只猫要用n+1维矩阵,最后一列用来操作。



#include<iostream>

using namespace std;
const int maxn = 105;
typedef long long LL;
struct matrix {
LL v[maxn][maxn];
matrix() { memset(v, 0, sizeof(v)); }
};
matrix T, ans;
int N, M, K;

void init()
{
char w[2];
memset(T.v, 0, sizeof(T.v));
for (int i = 0; i <= N; i++) //初始化为单位矩阵
T.v[i][i] = 1;
int x, y;
while (K--)
{
scanf("%s", w);
switch (w[0])
{
case 'g'://得到一个,最后一列加一
scanf("%d", &x);
T.v[x-1]
++;
break;
case 'e'://该行清空
scanf("%d", &x);
for (int i = 0; i <= N; i++)
T.v[x - 1][i] = 0;
break;
case 's'://交换
scanf("%d%d", &x, &y);
for (int i = 0; i <= N; i++)
swap(T.v[x - 1][i], T.v[y - 1][i]);
break;
default:break;
}
}
}

matrix mul(matrix x, matrix y)
{
matrix res;
for (int i = 0; i <= N; i++)
for (int k = 0; k <= N; k++)
if (x.v[i][k])
for (int j = 0; j <= N; j++)
res.v[i][j] += x.v[i][k] * y.v[k][j];
return res;
}
matrix matrix_mi(matrix p, int k)    //快速幂
{
matrix res;
for (int i = 0; i <= N; i++) res.v[i][i] = 1;
while (k)
{
if (k & 1)
res = mul(res, p);
p = mul(p, p);
k >>= 1;
}
return res;
}

int main()
{
while (~scanf("%d%d%d", &N, &M, &K))
{
if (N == 0 && M == 0 && K == 0) break;
init();
ans = matrix_mi(T, M);
for (int i = 0; i < N; i++)
printf("%lld ", ans.v[i]
);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 矩阵快速幂