题目描述

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

操作序列是一个长度不超过6且循环执行、每秒执行一个字符的字符串。每秒钟,所有格子同时执行各自操作序列里的下一个字符。序列中的每个字符是以下格式之一:

数字\(0\text{-}9\):表示拿\(0\text{-}9\)个石头到该格子。

\(NWSE\):表示把这个格子内所有的石头推到相邻的格子,\(N\)表示上方,\(W\)表示左方,\(S\)表示下方,\(E\)表示右方。

\(D\):表示拿走这个格子的所有石头。

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

输入描述:

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

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

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

输出描述:

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

示例1

输入

1 6 10 3

011112

1E

E

0

输出

3

说明

这是另一个类似于传送带的结构。左边的设备0间隔地产生石头并向东传送。设备1向右传送,直到设备2。10秒后,总共产生了5个石头,2个在传送带上,3个在最右边。

题解

很有思维难度的一个题目。但是这题无论哪里都没有给出\(T\)的数据范围,这谁看的出来是矩阵快速幂啊...

将当前矩阵写成一个一维向量,并且钦定\(f[0]=1\),那么\(i*(m-1)+j\)代表的就是原来位置\((i,j)\)的石头数量。

因为操作序列长度小于等于\(6\),而\(\gcd(1,2,3,4,5,6)=60\),也就是说每个操作序列在重复\(60\)次后都一定会回到位置\(1\)。那么可以把\(T\)分成\(\lfloor \frac T {60}\rfloor\)和\(T\mod 60\)两部分。

构造\(c[pos]\)表示第\(pos\)次操作的转移矩阵。(这里用\((i,j)\)表示坐标\((i,j)\)在一维向量中的位置)

  • 当操作\(s[i]\)为数字,\(c[pos][0,(i,j)]=s[i]\),\(c[pos][(i,j),(i,j)]=1\)
  • 当操作\(s[i]=S,E,W,N\)时,设移动后的位置为\((x,y)\),\(c[pos][(i,j),(x,y)]=1\)
  • 当操作\(s[i]=D\)时,\(c[pos][(i,j),(i,j)]=0\)

设\(C=\prod _{i=1}^{60} c_i\),\(r=T \mod 60\),那么答案即为\(f*C*\prod _{i=1}^r c_r\)

#include <bits/stdc++.h>
using namespace std; typedef long long ll;
const int N = 110; ll T;
int n, m, lim, len[N], act, now[10][10];
char s[10][10], t[10][10]; struct mat {
ll a[65][65];
mat() {memset(a, 0, sizeof(a));}
mat operator * (mat &x) {
mat ans;
for(int i = 0; i <= lim; ++i)
for(int j = 0; j <= lim; ++j)
for(int k = 0; k <= lim; ++k)
ans.a[i][j] += a[i][k] * x.a[k][j];
return ans;
}
mat Pow(ll t, mat a) {
mat ans; ans.a[0][0] = 1;
while(t) {
if(t & 1) ans = ans * a;
a = a * a; t >>= 1;
}
return ans;
}
}c[61], C; int idx(int x, int y) {return (x - 1) * m + y;} void print(mat x, bool flag) {
puts("#####################");
if(flag) {
for(int i = 0; i <= lim; ++i) printf("%lld ", x.a[0][i]);
puts("");
return;
}
for(int i = 0; i <= lim; ++i) {
printf("%d: ", i);
for(int j = 0; j <= lim; ++j) {
printf("%lld ", x.a[i][j]);
}
puts("");
}
puts("#####################");
} int main() {
scanf("%d%d%lld%d", &n, &m, &T, &act);
lim = n * m;
for(int i = 1; i <= n; ++i) {
scanf("%s", t[i] + 1);
for(int j = 1; j <= m; ++j) t[i][j] -= '0', ++t[i][j];
}
for(int i = 1; i <= act; ++i) {
scanf("%s", s[i] + 1);
len[i] = strlen(s[i] + 1);
}
for(int pos = 1; pos <= 60; ++pos) {
c[pos].a[0][0] = 1;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
// putchar(s[t[i][j]][now[i][j]]);
now[i][j] = (now[i][j] % len[t[i][j]]) + 1;
if(s[t[i][j]][now[i][j]] >= '0' && s[t[i][j]][now[i][j]] <= '9') {
c[pos].a[0][idx(i, j)] = s[t[i][j]][now[i][j]] - '0';
c[pos].a[idx(i, j)][idx(i, j)] = 1;
} else {
if(s[t[i][j]][now[i][j]] == 'D') c[pos].a[idx(i, j)][idx(i, j)] = 0;
if(i > 1 && s[t[i][j]][now[i][j]] == 'N')
c[pos].a[idx(i, j)][idx(i - 1, j)] = 1;
if(i < n && s[t[i][j]][now[i][j]] == 'S')
c[pos].a[idx(i, j)][idx(i + 1, j)] = 1;
if(j > 1 && s[t[i][j]][now[i][j]] == 'W')
c[pos].a[idx(i, j)][idx(i, j - 1)] = 1;
if(j < m && s[t[i][j]][now[i][j]] == 'E')
c[pos].a[idx(i, j)][idx(i, j + 1)] = 1;
}
}
}
// puts("");
}
C = c[1];
for(int pos = 2; pos <= 60; ++pos) C = C * c[pos];
C = C.Pow(T / 60, C);
for(int pos = 1; pos <= T % 60; ++pos) {
// printf("Round # %d\n", pos);
C = C * c[pos];
// print(c[pos], 0);
// printf("The test # %d\n", pos);
// print(C, 1);
}
ll ans = 0;
for(int i = 1; i <= lim; ++i) ans = max(ans, C.a[0][i]);
printf("%lld\n", ans);
return 0;
}

牛客1024B 石头游戏的更多相关文章

  1. 牛客Wannafly挑战赛23 B.游戏

    游戏 题目描述 小N和小O在玩游戏.他们面前放了n堆石子,第i堆石子一开始有ci颗石头.他们轮流从某堆石子中取石子,不能不取.最后无法操作的人就输了这个游戏.但他们觉得这样玩太无聊了,更新了一下规则. ...

  2. 牛客网练习赛23 F 托米的游戏

    链接:https://www.nowcoder.com/acm/contest/156/F 来源:牛客网 题目描述 题目背景编不下去了 托米有一棵有根树 T, 树根为1,每轮他会在剩下的子树中等概率一 ...

  3. 牛客网 江西财经大学第二届程序设计竞赛同步赛 D.绕圈游戏-(跳青蛙游戏)找数的所有因子就可以了

    链接:https://ac.nowcoder.com/acm/contest/635/D来源:牛客网 D.绕圈游戏 433为了帮ddd提升智商,决定陪他van特殊的游戏.433给定一个带有n个点的环, ...

  4. 牛客练习赛46 C 华华跟奕奕玩游戏 (期望,概率)(详解)

    链接:https://ac.nowcoder.com/acm/contest/894/C 来源:牛客网 华华跟奕奕玩游戏 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K ...

  5. 牛客练习赛49 E 筱玛爱游戏 (线性基+博弈)

    链接:https://ac.nowcoder.com/acm/contest/946/E 来源:牛客网 筱玛爱游戏 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  6. 题解——牛客网Wannafly挑战赛23 B-游戏 (SG函数)

    前言 比赛的时候没学过SG函数的蒟蒻以为是道结论题,但是不是QwQ 和dummyummy巨佬一起推了快三个小时的规律 最后去问了真正的巨佬__stdcall __stdcall面带微笑的告诉我们,这是 ...

  7. 【面试笔试算法】牛客网一站通Offer编程题2016.4.19

    牛客网一站通offer (一)字符串变形 1. 题目: 对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形.首先这个字符串中包含着一些空格,就像"Hello Wor ...

  8. 牛客OI周赛7-提高组 A 小睿睿的等式

    链接:https://ac.nowcoder.com/acm/contest/371/A来源:牛客网 小睿睿在游戏开始时有n根火柴棒,他想知道能摆成形如“A+B=n”的等式且使用的火柴棒数也恰好等于n ...

  9. 牛客网第9场多校E(思维求期望)

    链接:https://www.nowcoder.com/acm/contest/147/E 来源:牛客网 题目描述 Niuniu likes to play OSU! We simplify the ...

随机推荐

  1. spring boot2.x中集成H2数据库

    H2数据库介绍  查看 在spring boot中集成 1.添加依赖 <dependency> <groupId>org.springframework.boot</gr ...

  2. Oracle Spatial分区应用研究之四:不同分区粒度+全局空间索引效率对比

    1.实验目的 在实验之前先回答这样一个问题——对同一份数据使用不同的分区粒度,但均创建全局空间索引,问:它们的全局空间索引一致吗? 怎样算是一致的呢?R-TREE的树结构一致算一致吗?空间索引条目数及 ...

  3. js实现html表格<td>标签中带换行的文本显示出换行效果

    遇见问题 如下内容中我写了几行,但是表格中并未按行显示,换行符反而变成了空格,于是想自己转换下 思考问题 1.可以看到表格的内容是后端传来的数据,于是想直接在后端转换下,把换行符替换成<br&g ...

  4. Windows下同时安装了Python2与Python3时如何使用RobotFrameWork

    由于windows下不能像linux那样指定python文件的运行路径,当电脑中即安装了python2,又安装了python3时,也不能在环境变量中都配置运行路径吧(当然是可以配置的,系统会按照靠前的 ...

  5. 【C++】继承和组合的概念?什么时候用继承?什么时候用组合?

    继承:通过扩展已有的类来获得新功能的代码重用方法 组合:新类由现有类的对象合并而成的类的构造方式 何时用继承?何时用组合? 1.如果二者间存在一个"是"的关系,并且一个类要对另外一 ...

  6. (语法基础)浅谈面向切面编程(AOP)

    一:前言 面向切面编程是一个很重要的编程思想,想要写出一个便于维护的程序,理解AOP并且能熟练的在实际编程中合理的运用AOP思想是很有必要的 二:AOP的基本概念 基础概念:AOP中文翻译面向切面编程 ...

  7. 004 Thymeleaf学习笔记

    1.Thymeleaf概述 SpringBoot并不推荐使用jsp,但是支持一些模板引擎技术:Freemarker.Thymeleaf.Mustache. 简单说, Thymeleaf 是一个跟 Ve ...

  8. Java后台验证

    前台的js验证,可以通过其他手段绕过,存在安全问题,所以引入Java后台进行验证 一.导入jar包 此为hibernate-validator jar包,进行Java后台验证使用,在Java 1.9及 ...

  9. go编译运行说明

    二  编译运行说明 1.1 编译 1)有了go源文件,通过编译器将其编译成机器可以识别的二进制码文件. 2)在该源文件目录下,通过 go build 对hello.go 文件进行编译.可以指定生成的可 ...

  10. 【LEETCODE】69、动态规划,easy,medium级别,题目:198、139、221

    package y2019.Algorithm.dynamicprogramming.easy; /** * @ProjectName: cutter-point * @Package: y2019. ...