poj-3735-Training little cats-矩阵快速幂
2016-05-29 17:57
513 查看
Link:http://poj.org/problem?id=3735
Description
Input
Output
Sample Input
Sample Output
Source
思路:
代码
Training little cats
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11954 Accepted: 2951
Description
Facer'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.
Input
The 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)
Output
For each test case, output n numbers in a single line, representing the numbers of peanuts the cats have.
Sample Input
3 1 6 g 1 g 2 g 2 s 1 2 g 3 e 2 0 0 0
Sample Output
2 0 1
Source
PKU Campus 2009 (POJ Monthly Contest – 2009.05.17), Facer
思路:
这个题我们看到m非常大,并且应该是牵涉到线性变化的,故我们自然而然的联想到矩阵快速幂,但是这个题比较难的便是矩阵的构造,因为一开始有n个小猫,我们可以想到nXn的矩阵,那么对于每个小猫有用的是1Xn矩阵,但是这样的话初始是矩阵为零矩阵,无法使用矩阵乘法由此我们修改矩阵为(n+1)X(n+1)矩阵,我们以此题测试数据为例。 我们默认从0开始!!!!!——————!!!!! 开始时 |1 0 0 0| |0 0 0 0| |0 0 0 0| |0 0 0 0| 我们找一个单位矩阵,用于记录变换 |1 0 0 0| |0 1 0 0| |0 0 1 0| |0 0 0 1| 如果给第一只小猫一个peanut的话变换矩阵变成 |1 1 0 0| |0 1 0 0| |0 0 1 0| |0 0 0 1| 连续给第二个小猫两次的话则依次为 |1 1 1 0| |0 1 0 0| |0 0 1 0| |0 0 0 1| |1 1 2 0| |0 1 0 0| |0 0 1 0| |0 0 0 1| 交换1,2小猫的peanut则相当于变换矩阵的对应1列和2列交换 |1 2 1 0| |0 0 1 0| |0 1 0 0| |0 0 0 1| 清空2猫的peanut则相当于变换矩阵的2列化为0 |1 1 0 0| |0 1 0 0| |0 0 0 0| |0 0 0 1| 综上a猫加一个peanut,变换矩阵M0a++; a猫清空peanut,变换矩阵a列化为0; a,b猫交换,a列与b列值交换 本题另一个精彩部分就是对于稀疏矩阵的乘法
代码
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn(105); int n; struct matrix { long long mat[maxn][maxn]; void zero() { for(int i=0; i<=n; i++) { for(int j=0; j<=n; j++) { this->mat[i][j]=0; } } } void unit() { zero(); for(int i=0; i<=n; i++) this->mat[i][i]=1; } matrix operator * (const matrix &a)const { matrix res; res.zero(); for(int k=0; k<=n; k++) { for(int i=0; i<=n; i++) { if(this->mat[i][k]) { for(int j=0; j<=n; j++) { res.mat[i][j]+=this->mat[i][k]*a.mat[k][j]; } } } } return res; } matrix operator ^(int k)const { matrix res; matrix B=*this; res.unit(); while(k) { if(k&1) res=res*B; k>>=1; B=B*B; } return res; } }; int main() { int m,k; matrix start; matrix operation; while(scanf("%d%d%d",&n,&m,&k),n||m||k) { start.zero(); start.mat[0][0]=1; char cmd; operation.unit(); int a,b; while(k--) { getchar(); cmd=getchar(); switch(cmd) { case 'g': scanf("%d",&a); operation.mat[0][a]++; break; case 'e': scanf("%d",&a); for(int i=0; i<=n; i++) operation.mat[i][a]=0; break; default: scanf("%d%d",&a,&b); for(int i=0; i<=n; i++) swap(operation.mat[i][a],operation.mat[i][b]); break; } } start=start*(operation^m); for(int i=1; i<n; i++) cout<<start.mat[0][i]<<" "; cout<<start.mat[0] <<endl; } return 0; }
相关文章推荐
- Python使用稀疏矩阵节省内存实例
- 数据结构(C语言描述)读书笔记之稀疏矩阵
- 稀疏矩阵的变带宽存储方法。
- 稀疏矩阵-----三元组顺序表
- 稀疏矩阵的加法(用十字链表实现A=A+B)
- 稀疏矩阵求最小或最大的K个特征值及其特征向量
- Spark中稀疏矩阵的存储方式
- HDU1575 Tr A
- 矩阵快速幂
- HDU 1005 Number Sequence
- hdu1757 矩阵快速幂--
- HDU 4979 A simple math problem.
- HDU 1575 Tr A
- HDU 2604 Queuing
- poj_3070 Fibonacci
- HDU2604 Queuing(矩阵快速幂模板)
- hdu 5667 Sequence【费马小定理+矩阵快速幂】
- LightOj 1006(矩阵快速幂)
- 矩阵快速幂求斐波那契数列 poj3070
- poj 3070 矩阵快速幂求斐波拉契数列