[题解]细胞自动机

news/2024/10/5 15:10:16/文章来源:https://www.cnblogs.com/Sinktank/p/18285664

给定一个长度为\(n\)\(01\)\(s\),用于表示一个环上的细胞的初始状态,其中第\(1\)个细胞与第\(2\)个、第\(n\)个细胞相邻;第\(n\)个细胞与第\(1\)个和第\(n-1\)个相邻。\(0\)表示细胞死亡,\(1\)表示细胞存活。接下来给定\(t\)轮操作,每一轮操作,根据上一轮细胞的状态更改此轮的状态。规则如下:

  • 如果上一轮中与该细胞相邻的\(2\)个细胞中正好有\(1\)个存活,那么此轮中该细胞存活。否则此轮中该细胞死亡。

给定正整数\(t\),请输出一个\(01\)串,表示\(t\)轮变化后每个细胞的存活状态。

数据范围:对于\(50\%\)的数据,保证\(3\le n\le 15\)\(1\le T\le 10^{15}\)
对于所有数据,保证\(3\le n\le 10^5\)\(1\le T\le 10^{15}\)

样例:

Sample #1

Input

7 1
0000001

Output

1000010
Sample #2

Input

5 3
01011

Output

10100

50pts - 矩阵快速幂解法 - \(O(n^3\log t)\)

考虑用广义矩阵乘法代替普通矩阵乘法:把两数相乘改为两数取与,两数相加改为两数去异或。

则可以构建初始矩阵和递推矩阵(拿\(6\)阶举例,其他同理):

\[A=\begin{bmatrix} 输入的01串\dots \end{bmatrix}, B=\begin{bmatrix} 0&1&0&0&0&1\\ 1&0&1&0&0&0\\ 0&1&0&1&0&0\\ 0&0&1&0&1&0\\ 0&0&0&1&0&1\\ 1&0&0&0&1&0 \end{bmatrix}\]

点击查看代码
#include<bits/stdc++.h>
#define N 510
#define int long long
using namespace std;
int n,t;
string s;
struct Matrix{int n,m;bool a[N][N];Matrix(int na,int ma){n=na,m=ma,memset(a,0,sizeof a);}bool* operator [](int x){return a[x];}Matrix(){memset(a,0,sizeof a);}Matrix operator*(const Matrix &b) const{Matrix res(n,b.m);for(int i=1;i<=n;i++){for(int j=1;j<=b.m;j++){for(int k=1;k<=m;k++){res[i][j]^=a[i][k]&b.a[k][j];}}}return res;}
}a,base;
void qpow(int b){while(b){if(b&1) a=a*base;base=base*base;b>>=1;}
}
signed main(){cin>>n>>t>>s;a.n=1,a.m=base.n=base.m=n;for(int i=1;i<=n;i++) a[1][i]=s[i-1]-'0';for(int i=1;i<=n;i++){int p1=i-1,p2=i+1;if(p1==0) p1+=n;if(p2==n+1) p2-=n;base[i][p1]=base[i][p2]=1;}qpow(t);for(int i=1;i<=n;i++) cout<<a[1][i];return 0;
}

但由于此方法复杂度是\(O(n^3\log T)\),空间是\(O(n^2)\),都无法承受。

100pts - 找规律&倍增 - \(O(n\log T)\)

假设现在有一个无限长的环:
...000000010000000...
进行变化(下面用#表示\(1\),空格表示\(0\)),发现:

                         #    //初始状态# #    //经过1次变化#   #    //经过2次变化# # # ##       #    //经过4次变化# #     # ##   #   #   ## # # # # # # ##               #    //经过8次变化# #             # ##   #           #   ## # # #         # # # ##       #       #       ## #     # #     # #     # ##   #   #   #   #   #   #   ## # # # # # # # # # # # # # # ##                               #    //经过16次变化# #                             # ##   #                           #   ## # # #                         # # # ##       #                       #       ## #     # #                     # #     # ##   #   #   #                   #   #   #   ## # # # # # # #                 # # # # # # # ##               #               #               #
# #             # #             # #             # #.............

很神奇地,我们发现这是一个分形图(谢尔宾斯基三角形)。

当然这不是重点,我们发现,经过\(2^k\)次变化后,只有一开始的活细胞左边第\(2^k\)个细胞和右边第\(2^k\)个细胞是活的,其他全是死的。

因此我们可以得知任意一种环上,变化\(2^k\)次后每个活细胞向左右的贡献,即:对于每个活细胞,将其左&右边第\(2^k\)个细胞状态取反,自己也取反。

通过把\(t\)二进制分解,可以转化成若干个\(2^k\)次变化,重复上述操作即可。

时间复杂度\(O(n\log t)\),可以通过。

注意是一个环,所以位置需要取模\(n\)

#include<bits/stdc++.h>
#define N 100010
#define int long long
using namespace std;
int n,t,a[2][N];
string s;
int modn(int a){return ((a%n)+n)%n;}
signed main(){cin>>n>>t>>s;bool cur=0;for(int i=0;i<n;i++) a[0][i]=s[i]-'0';for(int ii=0,w=1;ii<55;ii++,w<<=1){//k=2^iif(t&w){cur^=1;for(int i=0;i<n;i++) a[cur][i]=a[cur^1][i];for(int i=0;i<n;i++) if(a[cur^1][i]) a[cur][i]^=1,a[cur][modn(i-w)]^=1,a[cur][modn(i+w)]^=1;}}for(int i=0;i<n;i++) cout<<a[cur][i];return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/739556.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装Nexus3和使用Nexus3搭建私有docker镜像仓库

1、官网下载Nexus3: https://help.sonatype.com/en/download.html 2、上传到服务器后解压:tar -xf nexus-3.69.0-02-java8-unix.tar.gz3、修改运行nexus配置 【1】修运行nexus所使用的用户:vim /opt/nexus3/nexus-3.69.0-02/binexus.rc #修改默认登陆用户为admin #run_as_us…

(9)逻辑综合添加约束(时序、DRC)

一、前言dc综合是一个不断迭代的过程,如果设计的RTL代码不满足时序约束的需求,则需要重新进行修改,然后再去综合,一直迭代到时序满足需求。 二、面积约束面积约束指令:set_max_area 100面积约束的定义有三种,一种指的是两输入与非门的个数,一种是晶体管的个数,第三种是…

深度解析 Raft 分布式一致性协议

深度解析 Raft 分布式一致性协议本文参考转载至:浅谈 Raft 分布式一致性协议|图解 Raft - 白泽来了 - 博客园 (cnblogs.com) 深度解析 Raft 分布式一致性协议 - 掘金 (juejin.cn) raft-zh_cn/raft-zh_cn.md at master maemual/raft-zh_cn (github.com)本篇文章将模拟一个KV数…

nacos学习笔记之服务发现中心

一.什么是服务发现 在微服务中,服务的消费方需要调用服务的生产方,这样服务的消费方就需要知道服务的消费方的网络地址(ip+端口号)。 二、流程上图中服务实例本身并不记录服务生产方的网络地址,所有服务实例内部都会包含服务发现客户端(例如spring cloud中的ribbon)。 (…

第一次学习Java的碎碎念

2024年夏新的学习开始了; 今天做了什么? 在B站上收藏了黑马程序员学习Java的教学视频,观看了几篇入门教程,暂时学会了如何打开CMD,以及几个常见的CMD命令,例如盘符名称:、dir、cd目录、cd..、cls、exit等等,做了一个练习(利用cmd打开qq),学会了如何把应用程序的路径…

测试标题

测试摘要\[a /ge b /eq c \]

Java反射与Fastjson的危险反序列化

Preface 在前文中,我们介绍了 Java 的基础语法和特性和 fastjson 的基础用法,本文我们将深入学习fastjson的危险反序列化以及预期相关的 Java 概念。 什么是Java反射? 在前文中,我们有一行代码 Computer macBookPro = JSON.parseObject(preReceive,Computer.class); 这行代…

Win10双屏设置 之 鼠标不能从中间划过 问题解决

Win10双屏设置 之 鼠标不能从中间划过解决-百度经验 (baidu.com)

比赛获奖的武林秘籍:03 好的创意选取-获得国奖的最必要前提

本文主要介绍了大学生电子计算机类比赛和创新创业类比赛创意选取的重要性,并列举了好的创意选取和坏的创意选取的例子,同时说明了好的创意选取具有哪些特点,同时对常见的创意选取途径与来源进行了基本介绍。比赛获奖的武林秘籍:03 好的创意选取-获得国奖的最必要前提 摘要 …

阶段测试

Sre网络班阶段测试 一:用sed 命令修改/etc/fstab文件,删除文件中的空行,注释行,并保留文件备份(7分) 答案写这里:二: 用 find 命令查找出 /var/ 目录中大于1M且以db结尾的文件(7分) 答案写这里:三: 先判断当前主机是否安装了nginx包,如果没安装,则执行命令安装,…

时间序列分析专题——利用SPSS专家建模器进行建模

SPSS的专家建模器可以自动识别数据,给出最适合的模型,本章通过三个例题介绍如何使用SPSS实现时间序列分析。由于本人对时间序列分析的理解尚浅,做出模型后在论文上的呈现形式需要取查阅资料,以便更好地在论文上呈现 在此之前,我们还需要了解时间序列分析的一些基础的名词 …