CF1349C Orac and Game of Life(思维)

我们发现一个点什么时候开始变化决定于离他最近的开始变化的点是哪个,因此只要求出最短距离即可

朴素的想法是通过bfs从每个点往外遍历,但是复杂度过高。其实可以考虑从步数考虑,从步数为1的不断往外扩展。这样不会炸内存,复杂度也满意

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
char g[1010][1010];
int d[1010][1010];
struct node{
    int x,y;
};
vector<node> q[3020];
int in[1010][1010];
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
int main(){
    ios::sync_with_stdio(false);
    int n,m,t;
    cin>>n>>m>>t;
    int i,j;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            cin>>g[i][j];
        }
    }
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            for(int k=0;k<4;k++){
                int a=i+dx[k];
                int b=j+dy[k];
                if(a&&a<=n&&b&&b<=m){
                    if(g[a][b]==g[i][j]){
                        d[i][j]=1;
                        in[i][j]=1;
                        q[1].push_back({i,j});
                        break;
                    }
                }
            }
        }
    }
    for(i=1;i<=n+m;i++){
        int sz=q[i].size();
        if(sz){
            for(auto tmp:q[i]){
                for(int k=0;k<4;k++){
                    int a=tmp.x+dx[k];
                    int b=tmp.y+dy[k];
                    if(a&&a<=n&&b&&b<=m&&(!in[a][b])){
                        in[a][b]=1;
                        d[a][b]=i+1;
                        q[i+1].push_back({a,b});
                    }
                }
            }
        }
    }
    while(t--){
        ll a,b,c;
        cin>>a>>b>>c;
        if(d[a][b]==0){
            cout<<(g[a][b]-'0')<<endl;
            continue;
        }
        if(c<d[a][b]){
            cout<<(g[a][b]-'0')<<endl;
        }
        else{
            c++;
            c-=d[a][b];
            if(c%2==0){
                cout<<(g[a][b]-'0')<<endl;
            }
            else{
                cout<<((g[a][b]-'0')^1)<<endl;
            }
        }
    }
}
View Code

 

posted @ 2020-09-18 20:51  朝暮不思  阅读(192)  评论(0编辑  收藏  举报