当前位置:编程学习 > C/C++ >>

POJ 3150 Cellular Automaton

给你一个“轮”,在每一次运作中,对于每一个a[i],更新a[i]= sum( a[j] ) % m,其中(min ( |i-j| ,n-|i-j| )<=d),
问,运行了K次以后轮中的数字是多少。
明显矩阵乘法的题,构造矩阵b[i][j]=1 if((min ( |i-j| ,n-|i-j| )<=d)),else b[i][j]=0
其实大致可以猜出来b矩阵是有规律的,用log(k)*n^3方法求出来输出一看,是个循环矩阵,
那么就可以用第一行更新下面每一行,而第一行是n^2求出来的。
所以矩阵乘法时间复杂度变成了n^2,于是不TLE了。。。
 
代码写的很易做图,主要是练一下类的重载运算符,明白了const到底是干吗用的:
[cpp]  
bool operator <(const point b)const{  
    return a.x
}  
第一个const 保证b不被改变,第二个const 保证原变量不被改变。
写这些大致想保证该不被改变的就不被改变吧(否则出现编译错误)。。
[cpp]  
#include  
#define X 510  
int min(int a,int b){  
    return a
}  
int abs(int x){  
    return x<0?-x:x;  
}  
int t[X],m;  
struct matrix{  
    int a[X][X],n;  
    void operator *(matrix b){  
        long long c;  
        int i,j,k;  
        for(i=0;i
            c=0;  
            for(k=0;k
                c=(c+(long long)a[0][k]*b.a[i][k])%m;  
            t[i]=c;  
        }  
        for(i=0;i
        for(i=1;i
            for(j=1;j
                a[i][j]=a[i-1][j-1];  
            a[i][0]=a[i-1][n-1];  
        }  
    }  
    void print(){  
        int i,j;  
        for(i=0;i
            for(j=0;j
                printf("%d ",a[i][j]);  
        puts("");  
    }  
}as,tmp;  
int main(){  
    int i,j,k,d,n;  
    while(~scanf("%d%d%d%d",&n,&m,&d,&k)){  
        for(i=0;i
            for(j=0;j
                as.a[i][j]=0;  
                if(min(abs(i-j),n-abs(i-j))<=d)  
                     tmp.a[j][i]=1;  
                else tmp.a[j][i]=0;  
            }  
        for(i=0;i
        as.n=n;tmp.n=n;  
//      tmp.print();  
        while(k){  
            if(k&1)as*tmp;  
            k>>=1; tmp*tmp;  
//          tmp.print();  
        }  
        for(i=0;i
            printf("%d%c",as.a[0][i],i==n-1?'\n':' ');  
    }  
    return 0;  
}  
 
 
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,