abc460_D题解

Repeatedly Repainting
题意:给你一个h行w列网格,格点只有黑白,此时对所有格点进行一下操作10^100次: 将周围有黑色格点的白色格点变为黑色,将所有黑色格点变为白色。
h*w<=1e6
思路:因为是10100不可能模拟所以找规律,黑白点交换有周期。发现如果是’#’且周围有白色最后一定是’#’(因为黑白一直交换两次,且10100是偶数),当是’.’时我们可以发现其状态取决于与其距离最近的’#’距离的奇偶性。若为奇数则最终状态一定为 否则为 #。因为想让白点也进入同样的循环,要保证周围有黑点,交换偶数次周期所以奇数距离为’#’
坑点:极大值要设为偶数,不然过不了样例2

#include <bits/stdc++.h>
using namespace std;
#define pi pair<int,int>
const int N=1e6+10;
const int INF=1e9;
int h,w;
string a[N];
string b[N];
int dx[8]={0,1,0,-1,1,1,-1,-1};
int dy[8]={1,0,-1,0,1,-1,1,-1};
queue<pi> q;
bool check(int x,int y){
    if(x>=1&&x<=h&&y>=1&&y<=w) return true;
    else return false;
}
int main(){
    cin >> h >> w;
    vector<vector<int>> dis(h+1,vector<int>(w+1,INF));
    for(int i=1;i<=h;i++){
        cin >> a[i];
        a[i]=' '+a[i];
        b[i]=string(w+1,'.');
    }
    for(int i=1;i<=h;i++){
        for(int j=1;j<=w;j++){
            if(a[i][j]=='#'){
                for(int k=0;k<8;k++){
                    int nx=i+dx[k];
                    int ny=j+dy[k];
                    if(check(nx,ny)&&a[nx][ny]=='.') b[nx][ny]='#';
                }
            }
        }
    }
    for(int i=1;i<=h;i++) a[i]=b[i];
    for(int i=1;i<=h;i++){
        for(int j=1;j<=w;j++){
            if(b[i][j]=='#'){
                dis[i][j]=0;
                q.push({i,j});
            }
        }
    }
    while(!q.empty()){
        pi f=q.front();
        q.pop();
        int x=f.first;
        int y=f.second;
        for(int i=0;i<8;i++){
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(check(nx,ny)&&dis[nx][ny]==INF){
                dis[nx][ny]=dis[x][y]+1;
                q.push({nx,ny});
            }
        }
    }
   for(int i=1;i<=h;i++){
       for(int j=1;j<=w;j++){
           if(dis[i][j]%2==0) cout << '.';
           else cout << "#";
       }
       cout << '\n';
    }
}
posted @ 2026-06-02 20:52  zhangyirui  阅读(9)  评论(0)    收藏  举报