1. 程式人生 > 實用技巧 >CF1349C Orac and Game of Life(思維)

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