寝癖頭の解法

学習中の覚え書きを投稿、更新していきます。

AtCoder Problems in C++ #E - 砂の城 (Sandcastle)

第14回日本情報オリンピック 予選(過去問)から、その提出コードの解答例です。
AtCoderとは、コンテストを通じて、プログラミングやアルゴリズムを学習するサービスです。
atcoder.jp
プログラミングコンテストとは、「与えられた問題をいかに素早く、正確に」解くことができるかを競うものです。
競技プログラミング」を略して、「競プロ」などと呼ばれています。

#E - 砂の城 (Sandcastle)

atcoder.jp

僕が作成、提出したコードは、以下のとおりです。

/*
AtCoder Problems in C++
#E - 砂の城 (Sandcastle)
https://atcoder.jp/contests/joi2015yo/tasks/joi2015yo_e
提出コードの解答例
https://neguse-atama.hatenablog.com
*/
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll Q=1e9+7;
int main(void){
  ll h,w;
  cin>>h>>w;
  vector<vector<ll>> p(h,vector<ll>(w,-1)),see(h,vector<ll>(w,-1));
  queue<ll> q;
  for(ll i=0;i<h;i++){
    for(ll j=0;j<w;j++){
      char c;
      cin>>c;
      if(c=='.'){
        see[i][j]=0;
        q.push(i*Q+j);
      }else{
        p[i][j]=c-'0';
      }
    }
  }
  vector<ll> x={0,0,1,-1,1,1,-1,-1};
  vector<ll> y={1,-1,0,0,1,-1,1,-1};
  ll ans=0;
  while(!(q.empty())){
    ll s=q.front()/Q,t=q.front()%Q;
    q.pop();
    for(ll i=0;i<8;i++){
      ll a=s+x[i],b=t+y[i];
      if(a<0 || a>=h || b<0 || b>=w){
        continue;
      }
      p[a][b]--;
      if(p[a][b]<=0 && see[a][b]==-1){
        q.push(a*Q+b);
        see[a][b]=see[s][t]+1;
      }
    }
    ans=see[s][t];
  }
  cout<<ans<<endl;
  return 0;
}