《大白书》156页,LA3704(UVa 1386) 细胞自动机
来源:互联网 发布:裤哥大战淘宝店主 编辑:程序博客网 时间:2024/05/07 22:56
【问题描述】
一个细胞自动机包含n个格子,每个格子的取值为0~m-1。给定距离d,则每次操作后每个格子的值将变为到它距离不超过d的所有格子在操作之前的值之和除以m的余数,其中i和j的距离为min{|i-j|,n-|i-j|}。给定n,m,d,k和自动机各格子的初始值,你的任务是计算k次操作以后各格子的值。
如下图,n=5,m=3,d=1,一次操作将把图a变成图b。比如,与格子3距离不超过1的格子(即格子2,3,4)在操作之前的值分别是2,2,1,因此从 操作后格子3的值为(2+2+1)mod 3=2。
【输入格式】
第一行包含4个整数n,m,d,k。第二行包含n个0..m-1的整数,即各格子的初始值。
【输出格式】
输出一行,包含n个0..m-1的整数,即k次操作后各格子的值。
【输入样例】
【样例1】
5 3 1 1
1 2 2 1 2
【样例2】
5 3 1 10
1 2 2 1 2
【输出样例】
【样例1】
2 2 2 2 1
【样例2】
2 0 0 2 2
【数据范围】
1<=n<=500 1<=m<=10^6 0<=d
一开始看到这道题感觉应该是一道很神奇的暴力优化题,结果一看数据,果断放弃我这颗暴力的心。这道题真正的做法是用矩阵优化线性递推,来达到有2分快速幂的效果很好的把有关递推次数的时间复杂度转化到矩阵操作上,主要针对次数多递推关系不多的递推式(这种式子一般的递推准爆)。现在有了知识的基础再看这道题简直是显然,列好矩阵分分钟就搞定了。详细代码如下:
#include<cstdlib>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;const int maxn=505;int mod;struct mat{ ll v[maxn][maxn]; int m,n; mat() { memset(v,0,sizeof(v)); m=n=0; } friend mat operator*(mat a,mat b) { mat c; c.n=a.n;c.m=b.m; for(int j=1;j<=b.m;j++) for(int k=1;k<=a.m;k++) c.v[1][j]=(c.v[1][j]+a.v[1][k]*b.v[k][j])%mod; for(int i=2;i<=c.n;i++) { c.v[i][1]=c.v[i-1][b.m]; for(int j=2;j<=b.m;j++) c.v[i][j]=c.v[i-1][j-1]; } return c; }}a,b;mat qkpow(mat y,ll x){ mat t,c; c.m=c.n=y.m; for(int i=1;i<=c.m;i++) c.v[i][i]=1; t=y; while(x) { if (x&1) c=c*t; x=x>>1; t=t*t; } return c;}int read(){ int x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x;}mat work(mat a,mat b){ mat c; c.n=a.n;c.m=b.m; for(int i=1;i<=c.n;i++) for(int j=1;j<=b.m;j++) for(int k=1;k<=a.m;k++) c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%mod; return c;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n=read();mod=read(); int d,T; d=read();T=read(); a.m=1; a.n=n; for(int i=1;i<=n;i++) a.v[i][1]=read(); b.n=b.m=n; for(int j=1;j<=d+1;j++) b.v[1][j]=1; for(int j=n;j>n-d;j--) b.v[1][j]=1; for(int i=2;i<=n;i++) { b.v[i][1]=b.v[i-1][n]; for(int j=2;j<=n;j++) b.v[i][j]=b.v[i-1][j-1]; } b=qkpow(b,T); a=work(b,a); for(int i=1;i<=n;i++) printf("%d ",a.v[i][1]); return 0;}
1 0
- 《大白书》156页,LA3704(UVa 1386) 细胞自动机
- UVA细胞自动机题解
- UVa 457 线性细胞自动机
- 细胞自动机
- 《大白书》192页 uva 1329 合作网络
- UVa 457 Linear Cellular Automata(线性细胞自动机)
- 大白书 第三页
- 并行实现细胞自动机
- 细胞元自动机
- CellularAutomation(细胞自动机)
- neerc2006 细胞自动机
- java实现细胞自动机
- 大白书160页,uva 11542 乘积是平方的数
- UVa 11292(今天开始刷大白书了)
- 大白书练习题(持续更新……)UVa & livearchive
- 例题2.23 细胞自动机 LA3740
- 细胞自动机(生命游戏)源码
- 大白书DP习题
- 51nod-方阵与完全平方数(构造矩阵+dfs)
- Painter not active
- C++对象模型
- 三个水杯
- 创建手机信息页面(国际化和样式与主题)
- 《大白书》156页,LA3704(UVa 1386) 细胞自动机
- 可靠传输的实现—滑动窗口/ 流量控制/ 拥塞控制
- 51单片机pwm信号模拟
- 微信接入
- 排序の插入排序
- frameset标签设计页面
- C++静态库与动态库
- IFE-JS 任务一:零基础JavaScript编码(一)
- Docker cp 命令(用于容器与主机之间的数据拷贝)