• [CF1349C] Orac and Game of Life


    Description

    给个n*m的网格,里面一些格子一开始是白色(0),另一些是黑色(1),接下来网格可进行迭代,对于每次迭代,格子里颜色的变化遵循以下规则:若该格子有相邻格子的颜色与之相同,则颜色翻转;若该格子没有相邻格子的颜色与之相同,则颜色不变。有t次询问,每次询问都有i, j, p,表示问第i行第j列格子在第p次迭代后是什么颜色。

    Solution

    如果相邻的两个点有一样的颜色,就会在下一次操作中保持同样的颜色并开始变色

    考虑求出 (f[i][j]) 表示第 ((i,j)) 个点在多少次迭代后开始变色

    如果一个格子一开始就能变色,设 (f[i][j]=0),否则设 (f[i][j] = infty)

    从开始就能变色的格子开始 BFS,当做边权为 (1) 的最短路问题 BFS 即可

    处理询问时,如果一个格子的 (f[i][j]=infty),则取其原始颜色;如果 (time<f[i][j]),也取其原始颜色;如果 (time ge f[i][j]),则考虑 (time-f[i][j]) 的奇偶性,如果是奇数则与原始颜色相反,偶数则相同

    #include <bits/stdc++.h>
    using namespace std;
    
    
    #define int long long
    const int N = 1005;
    const int inf = 2e18;
    
    struct point {int x,y;};
    
    int n,m,q,x,y,z,f[N][N],a[N][N];
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>m>>q;
        memset(f,0x3f,sizeof f);
        memset(a,0xff,sizeof a);
        for(int i=1;i<=n;i++) {
            string s;
            cin>>s;
            for(int j=1;j<=m;j++) a[i][j]=s[j-1]=='1';
        }
        queue <point> qu;
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                if(a[i][j]==a[i-1][j] || a[i][j]==a[i+1][j] || a[i][j]==a[i][j-1] || a[i][j]==a[i][j+1]) {
                    f[i][j]=0;
                    qu.push({i,j});
                }
            }
        }
        while(qu.size()) {
            int i=qu.front().x,j=qu.front().y;
            qu.pop();
            int ni,nj;
            ni=i+1,nj=j;
            if(ni>=1 && nj>=1 && ni<=n && nj<=m) {
                if(f[ni][nj]>f[i][j]+1) {
                    f[ni][nj]=f[i][j]+1;
                    qu.push({ni,nj});
                }
            }
            ni=i-1,nj=j;
            if(ni>=1 && nj>=1 && ni<=n && nj<=m) {
                if(f[ni][nj]>f[i][j]+1) {
                    f[ni][nj]=f[i][j]+1;
                    qu.push({ni,nj});
                }
            }
            ni=i,nj=j-1;
            if(ni>=1 && nj>=1 && ni<=n && nj<=m) {
                if(f[ni][nj]>f[i][j]+1) {
                    f[ni][nj]=f[i][j]+1;
                    qu.push({ni,nj});
                }
            }
            ni=i,nj=j+1;
            if(ni>=1 && nj>=1 && ni<=n && nj<=m) {
                if(f[ni][nj]>f[i][j]+1) {
                    f[ni][nj]=f[i][j]+1;
                    qu.push({ni,nj});
                }
            }
        }
        for(int i=1;i<=q;i++) {
            cin>>x>>y>>z;
            if(z<f[x][y]) {
                cout<<a[x][y]<<endl;
            }
            else {
                cout<<(a[x][y]^((f[x][y]-z)&1))<<endl;
            }
        }
    }
    
  • 相关阅读:
    【流水账】2021-06-19 Day-09
    【流水账】2021-06-18 Day-08
    【流水账】2021-06-16 Day-06
    【流水账】2021-06-15 Day-05
    .Net调用Java的实现方法
    优先队列的实例题
    栈的相关程序题
    重载函数
    卡特兰数
    关于全排列的递归
  • 原文地址:https://www.cnblogs.com/mollnn/p/12880470.html
Copyright © 2020-2023  润新知