TZOJ--5480: 孤衾易暖 // POJ--3735 Training little cats (矩阵快速幂)
5480: 孤衾易暖
描述
哇,好难,我要放弃了(扶我起来,我还能A
寒夜纵长,孤衾易暖,钟鼓渐清圆。
生活也许有些不如意的地方,但是没有什么是拥有一只猫不能解决的,我最喜欢苏格兰折耳猫。
现在我有n只小猫,我要训练这些猫去满足我奇奇怪怪的需求。
就是要让他们去得到鱼,这样他们才会快乐。刚开始他们是没有鱼的
我对这些猫有3种训练要求:
第一种要求为get x,意为让第x只猫咪得到一条;
第二种要求为eat x,意为让第x只猫咪吃掉它所有的鱼;
第三种要求为exchange x y,意为让第x只猫咪和第y只猫咪交换他们的鱼。
人们经常都是复读机,猫也不例外,你给他们设定某组操作,让他们重复就好了。
他们需要重复执行某组操作(含有k个要求)m次,求最后它们都有多少只鱼。
输入
输入包括多组样例,读到文件结尾。
输入的第一行为三个整数n,m,k,代表有n只猫,要重复的次数m和k个要求组成的操作。
接下来有k行,每一行都有一个训练方式(m≤1,000,000,000, n≤100, k≤100)。
输出
对于每个样例都在一行上输出n个数,代表每只猫有多少只鱼。
样例输入
3 1 6
get 1
get 2
get 2
exchange 1 2
get 3
eat 2
样例输出
2 0 1
提示
第一只猫得到1条鱼,第2只猫得到1条鱼,第2只猫得到1条鱼,交换1和2的鱼数。
第1只猫现在有2条鱼,第2只猫现在有1条鱼。第三只猫有一条鱼,然后第二只猫的鱼被吃完。
所以第1只猫现在有2条鱼,第2只猫现在有0条鱼,第三只猫有1条鱼。而且只有一次,故输出2 0 1。
题目来源
题目链接:http://tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=5480
http://poj.org/problem?id=3735
两个题目是一样的,只不过一个英文题面一个中文题目
按照题目要求构造出矩阵,重复的次数用矩阵快速幂计算
对于题目要求的三种操作,可以按照下面的方法构造矩阵
第一种要求为get x,意为让第x只猫咪得到一条;
即x的位置+1
第二种要求为eat x,意为让第x只猫咪吃掉它所有的鱼;
即x的位置归0
第三种要求为exchange x y,意为让第x只猫咪和第y只猫咪交换他们的鱼。
即swap(x,y)
#include <bits/stdc++.h> using namespace std; #define LL __int64 struct A{ LL data[111][111]; int n; void ini(int nn){//初始化全0矩阵 n=nn; memset(data,0,sizeof(data)); } void dw(int nn){//单位矩阵 ini(nn); for(int i=0;i<=n;i++)data[i][i]=1; } A(){ n=2; memset(data,0,sizeof(data)); } }; int n; A operator* (A a,A b)//矩阵乘法,重载乘号 { A ans; for(int i=0;i<=n;i++) { for(int j=0;j<=n;j++) { if(a.data[i][j]==0)continue; for(int k=0;k<=n;k++) { ans.data[i][k]+=a.data[i][j]*b.data[j][k]; } } } return ans; } A operator^ (A a,int k)//矩阵次幂 { A ans; ans.dw(n); while(k) { if(k&1)ans=ans*a; a=a*a; k>>=1; } return ans; } int main(){ int m,k,x,y; A T; char ch[15]; while(~scanf("%d%d%d",&n,&m,&k)){ T.dw(n); while(k--){ scanf("%s",ch); if(ch[0]=='g'){ scanf("%d",&x); T.data[0][x]++; } else if(ch[0]=='e'){ if(ch[1]=='x'){ scanf("%d %d",&x,&y); for(int i=0;i<=n;i++){ swap(T.data[i][x],T.data[i][y]); } }else { scanf("%d",&x); for(int i=0;i<=n;i++){ T.data[i][x]=0; } } } } T=T^m; printf("%I64d",T.data[0][1]); for(int i=2;i<=n;i++){ printf(" %I64d",T.data[0][i]); } puts(""); } }
posted on 2018-12-03 21:16 Anidlebrain 阅读(243) 评论(0) 编辑 收藏 举报