Training little cats poj3735
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 9299 | Accepted: 2230 |
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
【题意】:有n只猫咪,开始时每只猫咪有花生0颗,现有一组操作,由下面三个中的k个操作组成:
1. g i 给i只猫咪一颗花生米
2. e i 让第i只猫咪吃掉它拥有的所有花生米
3. s i j 将猫咪i与猫咪j的拥有的花生米交换
现将上述一组操作做m次后,问每只猫咪有多少颗花生?
【题解】:m达到10^9,显然不能直接算。
因为k个操作给出之后就是固定的,所以想到用矩阵,矩阵快速幂可以把时间复杂度降到O(logm)。问题转化为如何构造转置矩阵?
说下我的思路,观察以上三种操作,发现第二,三种操作比较容易处理,重点落在第一种操作上。
有一个很好的办法就是添加一个辅助,使初始矩阵变为一个n+1元组,编号为0到n,下面以3个猫为例:
定义初始矩阵A = [1 0 0 0],0号元素固定为1,1~n分别为对应的猫所拥有的花生数。
对于第一种操作g i,我们在单位矩阵基础上使Mat[0][i]变为1,例如g 1:
1 1 0 0
0 1 0 0
0 0 1 0
0 0 0 1,显然[1 0 0 0]*Mat = [1 1 0 0]
对于第二种操作e i,我们在单位矩阵基础使Mat[i][i] = 0,例如e 2:
1 0 0 0
0 1 0 0
0 0 0 0
0 0 0 1, 显然[1 2 3 4]*Mat = [1 2 0 4]
对于第三种操作s i j,我们在单位矩阵基础上使第i列与第j互换,例如s 1 2:
1 0 0 0
0 0 0 1
0 0 1 0
0 1 0 0,显然[1 2 0 4]*Mat = [1 4 0 2]
现在,对于每一个操作我们都可以得到一个转置矩阵,把k个操作的矩阵相乘我们可以得到一个新的转置矩阵T。
A * T 表示我们经过一组操作,类似我们可以得到经过m组操作的矩阵为 A * T ^ m,最终矩阵的[0][1~n]即为答案。
上述的做法比较直观,但是实现过于麻烦,因为要构造k个不同矩阵。
有没有别的方法可以直接构造转置矩阵T?答案是肯定的。
我们还是以单位矩阵为基础:
对于第一种操作g i,我们使Mat[0][i] = Mat[0][i] + 1;
对于第二种操作e i,我们使矩阵的第i列清零;
对于第三种操作s i j,我们使第i列与第j列互换。
这样实现的话,我们始终在处理一个矩阵,免去构造k个矩阵的麻烦。
至此,构造转置矩阵T就完成了,接下来只需用矩阵快速幂求出 A * T ^ m即可,还有一个注意的地方,该题需要用到long long。
具体实现可以看下面的代码。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define maxn 110
typedef struct abcd
{
long long a[maxn][maxn];
} abcd;
abcd a,b;
int n;
void mul(abcd x,abcd &y)
{
abcd z;
memset(z.a,,sizeof(z.a));
int i,j,k;
for(k=; k<=n; k++)
for(i=; i<=n; i++)
if(x.a[i][k])
for(j=; j<=n; j++)
z.a[i][j]+=x.a[i][k]*y.a[k][j]; for(i=; i<=n; i++)
for(j=; j<=n; j++)y.a[i][j]=z.a[i][j];
}
void fun(long long m)
{
int i,j;
memset(b.a,,sizeof(b.a));
for(i=; i<=n; i++)
b.a[i][i]=;
while(m)
{
if(m&)
{
mul(a,b);
}
m>>=;
mul(a,a);
}
}
int main()
{
int k,i,y,yy,j;
int m;
char x;
while(scanf("%d%d%d",&n,&m,&k),(n||m||k))
{
memset(a.a,,sizeof(a.a));
for(i=; i<=n; i++)a.a[i][i]=;
for(i=; i<k; i++)
{
getchar();
x=getchar();
if(x=='g')
{
scanf("%d",&y);
a.a[][y]++;
}
else if(x=='s')
{
scanf("%d%d",&y,&yy);
for(j=; j<=n; j++)swap(a.a[j][y],a.a[j][yy]);
}
else if(x=='e')
{
scanf("%d",&y);
for(j=; j<=n; j++)a.a[j][y]=;
}
}
fun(m);
for(i=; i<n; i++)printf("%I64d ",b.a[][i]);
printf("%I64d\n",b.a[][i]);
}
}
Training little cats poj3735的更多相关文章
- Training little cats(poj3735,矩阵快速幂)
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10737 Accepted: ...
- [POJ3735]Training little cats
题目:Training little cats 链接:http://poj.org/problem?id=3735 分析: 1)将操作用矩阵表示出来,然后快速幂优化. 2)初始矩阵:$ \left[ ...
- 矩阵快速幂 POJ 3735 Training little cats
题目传送门 /* 题意:k次操作,g:i猫+1, e:i猫eat,s:swap 矩阵快速幂:写个转置矩阵,将k次操作写在第0行,定义A = {1,0, 0, 0...}除了第一个外其他是猫的初始值 自 ...
- [POJ 3735] Training little cats (结构矩阵、矩阵高速功率)
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9613 Accepted: 2 ...
- POJ 3735 Training little cats<矩阵快速幂/稀疏矩阵的优化>
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13488 Accepted: ...
- POJ 3735 Training little cats(矩阵快速幂)
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11787 Accepted: 2892 ...
- POJ 3735:Training little cats 联想到矩阵相乘
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11208 Accepted: ...
- xiaowuga poj3735—Training little cats(特殊操作转化为矩阵操作)
题意:有n只猫,对其进行k次操作,然后反复这样操作m次. 其中g 表示 i 猫加1, e表示 i 猫为0:s表示 i 与 j 猫互换. 解释一下样例: 3 1 6g 1g 2g 2s 1 2g 3e ...
- poj3735—Training little cats(特殊操作转化为矩阵操作)
题目链接:http://poj.org/problem?id=3735 题目意思: 调教猫咪:有n只饥渴的猫咪,现有一组羞耻连续操作,由k个操作组成,全部选自: 1. g i 给第i只猫咪一颗花生 2 ...
随机推荐
- Python学习笔记3
__slots__ 如果我们想要限制class的属性怎么办?比如,只允许对Student实例添加name和age属性. 为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__s ...
- 使用 qemu 搭建内核开发环境
本文主要介绍在 MacOS 上使用 qemu 搭建 Linux Kernel 的开发环境.(在开始之前需要注意的是,本文中的 Linux 开发环境是一个远程服务器,而 qemu 被安装在本地的 Mac ...
- 自己动手写java 字节流输入输出流
数据流是一串连续不断的数据的集合,就象水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流. "流是磁盘或其它外围设备中存储的数据的源点或终点." ...
- leetcode 001 Two Sun
Given an array of integers, return indices of the two numbers such that they add up to a specific ta ...
- .Net Mvc实现各种表格随意切换插件
一套Js代码,.只要改参数 在3种表格之间任意切换-(使用Js面向对象封装,可重写方法) 任意表格皮肤随便切换 flextgrid/bootstrapt/jqgrid 1 001 @{ 002 ...
- new和newInstance区别
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp55 在初始化一个类,生成一个实例的时候:newInstance() ...
- poj 1523求割点
题意:给出一个无向图,求割点以及去除这个点后图分为几部分: 思路:割点定义:去掉该点后图将分成几个部分.割点:(1)当k为根节点且有>1个分支,则去除该点后图便被分成几个分支.(2)DFN[v] ...
- Java课设--俄罗斯方块Tetris
Java程序设计课程作业报告 作业:俄罗斯方块游戏 姓名 赵璐媛 学号 程序得分 90% 作业报告 得分10% 实验总分 100% 作业目的: 掌握基本的图形程序设计方法 掌握Java事件处理程序编写 ...
- 201521123083《Java程序设计》第9周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...
- 团队作业4---第一次项目冲刺(ALpha)版本 第五天
一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 a.完成所有基础功能 b.正在进行测试调试 四.困难与问题 1.根据测试需求功能,部分基础功能不能实现,性能不达标,后续已完成 ...