POJ3735

题目链接:http://poj.org/problem?id=3735

解题思路:

  先构造一个(n+1)*(n+1)的单位矩阵E,在此基础上进行操作:

  1、g i     ------------->      E[0][i] ++;

  2、s i j   ------------->  for(int k=0;k<=n;k++)  swap(E[k][i],E[k][j]);

  3、e i    ------------->  for(int k=0;k<=n;k++) E[k][i]=0;

  上面的这一个部分本来我是构造多个单位矩阵,在单位矩阵上进行操作的,操作后的矩阵相乘的结果就是总的操作,结果就是一个TLE。。。后来改成这样才AC了。

  然后再构造一个矩阵A,A只有左上角为1,其他的都为0。操作m次,其实就是A*(E^m)。矩阵快速幂,上!

AC代码:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const int maxn=110;
 8 struct Matrix{
 9     ll mat[maxn][maxn];
10 };
11 Matrix Multiply(Matrix x,Matrix y,int n){
12     Matrix temp;
13     for(int i=0;i<=n;i++){
14         for(int j=0;j<=n;j++){
15             temp.mat[i][j]=0;
16             for(int k=0;k<=n;k++){
17                 if(x.mat[i][k]&&y.mat[k][j])    //没有这个优化TLE
18                     temp.mat[i][j]+=(x.mat[i][k]*y.mat[k][j]);
19             }
20         }
21     }
22     return temp;
23 }
24 Matrix Fast_Power(Matrix a,int m,int n){
25     Matrix res;
26     for(int i=0;i<=n;i++){
27         for(int j=i;j<=n;j++){
28             if(i==j)    res.mat[i][j]=1;
29             else    res.mat[i][j]=res.mat[j][i]=0;
30         }
31     }
32     while(m){
33         if(m&1) res=Multiply(res,a,n);
34         m>>=1;
35         a=Multiply(a,a,n);
36     }
37     return res;
38 }
39
40 int main(){
41     Matrix rt;
42     int n,m,k,a,b;
43     char t[3];
44     while(scanf("%d%d%d",&n,&m,&k)==3&&(n||m||k)){
45         for(int i=0;i<=n;i++){
46             for(int j=i;j<=n;j++){
47                 if(i==j)    rt.mat[i][j]=1;
48                 else    rt.mat[i][j]=rt.mat[j][i]=0;
49             }
50         }//构造出一个(n+1)*(n+1)的单位矩阵
51         while(k--){
52             scanf("%s",t);
53             if(t[0]==‘g‘){
54                 scanf("%d",&a);
55                 rt.mat[0][a]++;
56             }
57             else if(t[0]==‘e‘){
58                 scanf("%d",&a);
59                 for(int i=0;i<=n;i++)
60                     rt.mat[i][a]=0;
61             }
62             else{
63                 scanf("%d %d",&a,&b);
64                 for(int i=0;i<=n;i++){
65                     if(rt.mat[i][a]||rt.mat[i][b])
66                         swap(rt.mat[i][a],rt.mat[i][b]);
67                 }
68             }
69         }
70         if(m==0){
71             for(int i=0;i<n;i++){
72                 if(i!=0)    printf(" ");
73                 printf("0");
74             }
75         }
76         else{
77             Matrix t;
78             memset(t.mat,0,sizeof(t));
79             t.mat[0][0]=1;
80             Matrix ret=Multiply(t,Fast_Power(rt,m,n),n);
81             for(int i=1;i<=n;i++){
82                 if(i!=1)    printf(" ");
83                 printf("%lld",ret.mat[0][i]);
84             }
85         }
86         printf("\n");
87     }
88     return 0;
89 }
时间: 2024-11-14 14:56:55

POJ3735的相关文章

POJ3735 Training little cats DP,矩阵快速幂,稀疏矩阵优化

题目大意是,n只猫,有k个动作让它们去完成,并且重复m次,动作主要有三类gi,ei,s i j,分别代表第i只猫获得一个花生,第i只猫吃掉它自己所有的花生,第i只和第j只猫交换彼此的花生.k,n不超过100,m不超过1000,000,000,计算出最后每只猫还剩下多少个花生. 我们假设一个n维向量P,每个分量的值代表这n只猫所拥有的花生数,那么对于gi操作其实就是在第i维分量上加上1:对于ei,那就是在第i维分量上乘以0,说到这里,有木有感觉这很像3D坐标转化中的平移矩阵和缩放矩阵?没错,就是这

poj3735,,矩阵快速幂

Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9815   Accepted: 2346 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 th

POJ3735 矩阵

题意:有n只猫咪,开始时每只猫咪有花生0颗,现有一组操作,由下面三个中的k个操作组成:        1. g i 给i只猫咪一颗花生米        2. e i 让第i只猫咪吃掉它拥有的所有花生米        3. s i j 将猫咪i与猫咪j的拥有的花生米交换        现将上述一组操作做m次后,问每只猫咪有多少颗花生? sol: 可参考Matrix67<十个利用矩阵乘法解决的经典题目> 定义初始矩阵A = [1 0 0 0],0号元素固定为1,1~n分别为对应的猫所拥有的花生数.

poj3735—Training little cats(特殊操作转化为矩阵操作)

题目链接:http://poj.org/problem?id=3735 题目意思: 调教猫咪:有n只饥渴的猫咪,现有一组羞耻连续操作,由k个操作组成,全部选自: 1. g i 给第i只猫咪一颗花生 2. e i 让第i只猫咪吃光它的花生 3. s i j 交换猫咪i与猫咪j的花生 现将上述一组连续操作做m次后,求每只猫咪有多少颗花生? 思路:这道题难点在如何把这种奇怪的操作转化为矩阵操作,网络上看到一个画的很好的图,这里直接偷过来. 现在,对于每一个操作我们都可以得到一个转置矩阵,把k个操作的矩

Training little cats(poj3735,矩阵快速幂)

Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10737   Accepted: 2563 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 t

TZOJ--5480: 孤衾易暖 // POJ--3735 Training little cats (矩阵快速幂)

5480: 孤衾易暖 时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte 描述 哇,好难,我要放弃了(扶我起来,我还能A 寒夜纵长,孤衾易暖,钟鼓渐清圆. 生活也许有些不如意的地方,但是没有什么是拥有一只猫不能解决的,我最喜欢苏格兰折耳猫. 现在我有n只小猫,我要训练这些猫去满足我奇奇怪怪的需求. 就是要让他们去得到鱼,这样他们才会快乐.刚开始他们是没有鱼的 我对这些猫有3种训练要求: 第一种要求为get x,意为让第x只猫咪得到一条: 第二种要求为e

矩阵快速幂专题(三)

哈哈哈,博主又回来了!这次专题是第三弹也是最后一弹了,这次会对矩阵进行一个小收尾.做完这25道题,我感觉到其实我矩阵学得并不好,还有许多知识点没有学会.后面看情况可能还会继续开矩阵的专题,那应该是几个月以后的事了.从下周开始,应该会先学习一下数论的相关算法! 这次的七道题目(为什么题目越来越少了)主要是针对了矩阵的优化,对于会TLE的和MLE(内存爆了)的矩阵而且这个矩阵又恰好是同构矩阵(同构矩阵是啥?)的话,可以采用一维数组来模拟二维,从而降低复杂度.降低空间.(竟然是罕见的同时降时间和空间的

week0

Time: 2014.4.21~2014.4.27 poj3176 题意:数塔 思路:dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j]; Code: poj3176.cpp poj2229 题意:仅用1,2,4,8...组成n的方案数对10^9取余 思路:n为奇数 dp[n]=dp[n-1] (写成 dp[n]=dp[n-1]+dp[n-2]+dp[n-4]+... 的话想想,是不是会算重) 同理,n为偶数 dp[n]=dp[n-1]+dp[n/2] (