AcWing 206. 石头游戏

石头游戏在一个 n 行 m 列 (1≤n,m≤8) 的网格上进行,每个格子对应一种操作序列,操作序列至多有10种,分别用0~9这10个数字指明。

操作序列是一个长度不超过6且循环执行、每秒执行一个字符的字符串。

每秒钟,所有格子同时执行各自操作序列里的下一个字符。

序列中的每个字符是以下格式之一:

1、数字0~9:表示拿0~9个石头到该格子。
2、NWSE:表示把这个格子内所有的石头推到相邻的格子,N表示上方,W表示左方,S表示下方,E表示右方。
3、D:表示拿走这个格子的所有石头。

给定每种操作序列对应的字符串,以及网格中每个格子对应的操作序列,求石头游戏进行了 t 秒之后,石头最多的格子里有多少个石头。

在游戏开始时,网格是空的。

输入格式

第一行4个整数n, m, t, act。

接下来n行,每行m个字符,表示每个格子对应的操作序列。

最后act行,每行一个字符串,表示从0开始的每个操作序列。

输出格式

一个整数:游戏进行了t秒之后,所有方格中石头最多的格子有多少个石头。

输入样例:

1 6 10 3
011112
1E
E
0

输出样例:

3

样例解释

样例中给出了三组操作序列,第一个格子执行编号为0的操作序列”1E”,第二至五个格子执行编号为1的操作序列”E”,第六个格子执行编号为2的操作序列”0”。

这是另一个类似于传送带的结构,左边的设备0间隔地产生石头并向东传送。

设备1向右传送,直到设备2。

10秒后,总共产生了5个石头,2个在传送带上,3个在最右边。

题解:我们可以把网格看成一维向量,下标从1开始,num(i,j) = (i-1)*m+j;

   我们可以定义一个状态矩阵f,下标从0~n*m,其中f[num(i,j)]记录格子(i,j)中石头个数。

      操作序列长度不超过6,1~6的最小公倍数为60,所以经过60s后所有序列都会处于重新开始的位置。每60s一个循环,我们只需记录第一个60s。

   对于1~60之间的每一秒k,所有格子操作可以构成一个状态矩阵,矩阵行列下标都是0~n*m,构造方法如下:

  1. 若网格(i,j)第k秒的操作字符为“N”,且i>1,则令Ak[num(i,j),num(i-1,j)] = 1,表示把石子推到上面的格子里。“W”、“S”、“E”类似。
  2. 若网格(i,j)第k秒的操作字符为数字x,则令Ak[0,num(i,j)] = x,Ak[num(i,j),num(i,j)] = 1。
  3. 令Ak[0,0] = 1。 (保证f[0]始终为1)
  4. 其他部分赋值为0。

   最后求出f中的最大值。

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 70
#define mod 1000000007
#define ll long long
int n,m,t,act;
struct Matrix
{
long long ma[maxn][maxn];
Matrix() {
memset(ma,, sizeof(ma));
}
}f,e[maxn],d;
Matrix mul(Matrix A,Matrix B)
{
Matrix C;
for(int i=;i<maxn;i++)
for(int j=;j<maxn;j++)
for(int k=;k<maxn;k++)
C.ma[i][j] += (A.ma[i][k]*B.ma[k][j]);
return C;
}
Matrix cel(Matrix A,Matrix B) {
ll w[]={};
for(int j=;j<=n*m;j++)
for(int k=;k<=n*m;k++)
w[j]+=A.ma[][k]*B.ma[k][j];
memcpy(A.ma[],w,sizeof(w));
return A;
}
Matrix pow_mod(Matrix A,long long t)
{
Matrix B = d;
while(t) {
if(t&) A = cel(A,B); //可直接mul(f,e[i]);
B=mul(B,B);
t>>=;
}
return A;
}
char s[][],cz[maxn][];
int len[maxn];
int num(int i,int j) {return (i-)*m+j;}
int main()
{
scanf("%d%d%d%d",&n,&m,&t,&act);
for (int i = ; i <= n; i++) scanf("%s",s[i]+);
for (int i = ; i < act; i++) scanf("%s",cz[i]),len[i] = strlen(cz[i]);
for (int k = ; k <= ; k++) {
e[k].ma[][] = ;
for (int i = ; i <= n; i++) {
for (int j = ; j <= m; j++) {
int x = s[i][j] - '', y = (k-)%len[x];
if (cz[x][y] >= '' && cz[x][y] <= '') {
e[k].ma[][num(i,j)] = cz[x][y]-'';
e[k].ma[num(i,j)][num(i,j)] = ;
} else if (cz[x][y] == 'N' && i->) e[k].ma[num(i,j)][num(i-,j)] = ;
else if (cz[x][y] == 'W' && j->) e[k].ma[num(i,j)][num(i,j-)] = ;
else if (cz[x][y] == 'S' && i+<=n) e[k].ma[num(i,j)][num(i+,j)] = ;
else if (cz[x][y] == 'E' && j+<=m) e[k].ma[num(i,j)][num(i,j+)] = ;
}
}
if (k == ) d = e[];
else d = mul(d,e[k]);
}
ll ans = ;
f.ma[][] = ;
f = pow_mod(f,t/);
int z = t%;
for (int i = ; i <= z; i++) f = cel(f,e[i]); //可直接mul(f,e[i]);
for (int i = ; i <= n*m; i++) ans = max(ans,f.ma[][i]);
printf("%lld\n",ans);
return ;
}

AcWing 206. 石头游戏 矩阵乘法|矩阵快速幂的更多相关文章

  1. Luogu 3390 【模板】矩阵快速幂 (矩阵乘法,快速幂)

    Luogu 3390 [模板]矩阵快速幂 (矩阵乘法,快速幂) Description 给定n*n的矩阵A,求A^k Input 第一行,n,k 第2至n+1行,每行n个数,第i+1行第j个数表示矩阵 ...

  2. Luogu T7152 细胞(递推,矩阵乘法,快速幂)

    Luogu T7152 细胞(递推,矩阵乘法,快速幂) Description 小 X 在上完生物课后对细胞的分裂产生了浓厚的兴趣.于是他决定做实验并 观察细胞分裂的规律. 他选取了一种特别的细胞,每 ...

  3. bzoj 3240: [Noi2013]矩阵游戏 矩阵乘法+十进制快速幂+常数优化

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 613  Solved: 256[Submit][Status] ...

  4. poj3613:Cow Relays(倍增优化+矩阵乘法floyd+快速幂)

    Cow Relays Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7825   Accepted: 3068 Descri ...

  5. HDU4965 Fast Matrix Calculation —— 矩阵乘法、快速幂

    题目链接:https://vjudge.net/problem/HDU-4965 Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Othe ...

  6. BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 ...

  7. bzoj 3240 矩阵乘法+十进制快速幂

    首先,构造出从f[][i]->f[][i+1]的转移矩阵a,和从f[i][m]->f[i+1][1]的转移矩阵b, 那么从f[1][1]转移到f[n][m]就是init*(a^(m-1)* ...

  8. 【HDOJ5950】Recursive sequence(矩阵乘法,快速幂)

    题意:f[1]=a,f[2]=b,f[i]=2f[i-2]+f[i-1]+i^4(i>=3),多组询问求f[n]对2147493647取模 N,a,b < 2^31 思路:重点在于i^4的 ...

  9. 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)

    先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...

随机推荐

  1. codedecision P1113 同颜色询问 题解 线段树动态开点

    题目描述:https://www.cnblogs.com/problems/p/11789930.html 题目链接:http://codedecision.com/problem/1113 这道题目 ...

  2. 梯度下降优化算法综述与PyTorch实现源码剖析

    现代的机器学习系统均利用大量的数据,利用梯度下降算法或者相关的变体进行训练.传统上,最早出现的优化算法是SGD,之后又陆续出现了AdaGrad.RMSprop.ADAM等变体,那么这些算法之间又有哪些 ...

  3. 微信小程序中 不点击picker 点击一个button 怎么调用picker 弹出选择框

    把按钮放在picker区域里就好了 picker本身就是一个区域 <picker mode = "selector" class='info' bindchange=&quo ...

  4. nginx 301 将不带www域名,重定向到www域名

    // nginx 官方推荐 server { listen 80; server_name example.org; return 301 http://www.example.org$request ...

  5. uni-app学习记录07-生命周期

    <template> <view class="content"> 我是首页 </view> </template> <scr ...

  6. [转]Win10下安装Linux子系统

    工作以来一直DotNet系偏C/S, 接触Web开发的时间也不长, 现在主要偏向Web全栈方向, 一直对Linux系统心生向往, 夜深了娃睡了, 打开老旧的笔记本来折腾一下. 准备工作 控制面板 &g ...

  7. 4-10 items设计

    1,items相当于dict,但是又比字典好 2,parse.urljoin(response.url,post_url)方法,其中image_url是一个域名的话,其中的当前域名就不用再添加. yi ...

  8. 2019-11-6-Roslyn-how-to-use-WriteLinesToFile-to-write-the-semicolons-to-file

    title author date CreateTime categories Roslyn how to use WriteLinesToFile to write the semicolons t ...

  9. 基于 Laravel-Admin 在十分钟内搭建起功能齐全的后台模板

    http://laravelacademy.org/post/6468.html 1.简介 为 Laravel 提供后台模板的项目越来越多,学院君已陆续为大家介绍过Laravel Angular Ad ...

  10. Python--day37--守护进程和几个常用的方法

    1,p.daemon = True #设置子进程为守护进程 #守护进程会随着主进程的代码执行完毕 而结束 #子进程 --> 守护进程 import time from multiprocessi ...