zoukankan      html  css  js  c++  java
  • POJ

    cellular automaton is a collection of cells on a grid of specified shape that evolves through a number of discrete time steps according to a set of rules that describe the new state of a cell based on the states of neighboring cells. The order of the cellular automaton is the number of cells it contains. Cells of the automaton of order n are numbered from 1 to n.

    The order of the cell is the number of different values it may contain. Usually, values of a cell of order m are considered to be integer numbers from 0 to m − 1.

    One of the most fundamental properties of a cellular automaton is the type of grid on which it is computed. In this problem we examine the special kind of cellular automaton — circular cellular automaton of order n with cells of order m. We will denote such kind of cellular automaton as n,m-automaton.

    A distance between cells i and j in n,m-automaton is defined as min(|i − j|, n − |i − j|). A d-environment of a cell is the set of cells at a distance not greater than d.

    On each d-step values of all cells are simultaneously replaced by new values. The new value of cell i after d-step is computed as a sum of values of cells belonging to the d-enviroment of the cell i modulo m.

    The following picture shows 1-step of the 5,3-automaton.

    The problem is to calculate the state of the n,m-automaton after k d-steps.

    Input

    The first line of the input file contains four integer numbers nmd, and k (1 ≤ n ≤ 500, 1 ≤ m ≤ 1 000 000, 0 ≤ d < n2 , 1 ≤ k ≤ 10 000 000). The second line contains n integer numbers from 0 to m − 1 — initial values of the automaton’s cells.

    Output

    Output the values of the n,m-automaton’s cells after k d-steps.

    Sample Input

    sample input #1
    5 3 1 1
    1 2 2 1 2
    
    sample input #2
    5 3 1 10
    1 2 2 1 2

    Sample Output

    sample output #1
    2 2 2 2 1
    
    sample output #2
    2 0 0 2 2

    题意:题面很臭很长。大意是,有一个大小为N的环,给出M,K,D,以及N个数。我们进行K次操作,每次操作把距离当前点不超过D的累加到当前点,结果模M。

    思路:因为要进行K次,每次的原则是一样的,我们可以想到用矩阵来优化,如果i能到达j,把么base[i][j]=1;则结果ans=A*(base^K)。

    但是需要优化,时间复杂度为O(N^3*lgK)。我们发现矩阵是下一行由上一行右移一位而来,那么我们保存一维即可代表这个矩阵。同样的,我们只需要得到第一行的矩阵结果,就能得到整个矩阵的结果。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=510;
    int N,Mod,D,K;
    struct mat
    {
        int M[maxn];
        mat(){ rep(i,1,N) M[i]=0; }
        mat friend operator*(mat a,mat b){
            mat res;
            rep(k,1,N)
             rep(j,1,N){
                res.M[j]=(res.M[j]+(ll)a.M[k]*b.M[j-k+1>0?j-k+1:j-k+1+N]%Mod)%Mod;
             }
            return res;
        }
        mat friend operator ^(mat a,int x)
        {
           mat res;rep(i,1,N) res.M[1]=1;
           while(x){
              if(x&1) res=res*a; a=a*a; x/=2;
           } return res;
        }
    
    };
    int main()
    {
        scanf("%d%d%d%d",&N,&Mod,&D,&K);
        mat a,base;
        rep(i,1,N) scanf("%d",&a.M[i]);
        rep(i,1,N)
          if(i-1<=D||N-i+1<=D||N-1+i<=D) base.M[i]=1;
        a=a*(base^K);
        rep(i,1,N-1) printf("%d ",a.M[i]);
        printf("%d
    ",a.M[N]);
        return 0;
    }
  • 相关阅读:
    APP测试点总结
    总结了一些指针易出错的常见问题(四)
    总结了一些指针易出错的常见问题(三)
    总结了一些指针易出错的常见问题(二)
    C++/C头文件 .h和 .c
    今天研究了一下手机通信录管理系统(C语言)
    Android软件测试Monkey测试工具
    nio之netty3的应用
    java io之管道流
    java nio之Buffer
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9669655.html
Copyright © 2011-2022 走看看