[アルゴリズム]BOJ 2573(氷山)
ソース:https://www.acmicpc.net/problem/2573
地球温暖化で北極氷山が溶けている.図1に示すように、氷山を2次元アレイに表示します.氷山の各部分の高さ情報は,配列された各セルに正の整数として格納される.氷山以外の海に対応する格には0が格納されている.図1では、スペースはすべてゼロで埋め込まれていると思います.
図1.行数5、列数7の2 Dアレイの氷山の高さ情報を格納します.
氷山の高さは海水との接触が多い場所でより速く減少するため、配列中の氷山の各部分に対応する格子の高さは毎年、格子の中で東西南北4方向に付着する0の格子の個数を減少させる.ただし、各セルに格納される高さは0より小さくなりません.海水は湖水のように氷山に囲まれているかもしれない.従って、図1の氷山は、図2に示すように1年後に変形する.
図3は、図1の氷山の2年後の変化を示す.2 D配列では,東西南北方向の格子が互いに接続されている.したがって、図2の氷山は1つであり、図3の氷山は3つに分かれている.
氷山が1つ与えられた場合、プログラムを作成して、この氷山が2つ以上分離された最初の時間(年)を求めます.図1の氷山について、答えは2です.全てが溶けるまで2つ以上離さないと、プログラムは0を出力します.
1行目では、2つの整数NとMは、2次元配列の行数と列数を表すスペースで区切られます.NとMは3以上300以下である.次のN行では、各行の間にスペースがあり、M個の整数は配列の各行を表します.各グリッドの値は0以上10以下です.配列では、氷山が占める格の個数、すなわち1以上の整数が占める格の個数が10000以下である.配列の最初の行と最後の行と最後の列は常に0で埋め込まれます.
1行目は氷山分離の最初の時間(年)を出力する.氷山が溶けるまで分離していない場合は0を出力します.
すぐに問題を解決したいだけで、多くの間違いを犯した.問題がうまく読めず、条件 を漏らした.
乱編コードのため、モジュール化は行われていない. この2つの理由で、デバッグに時間がかかりました.
私の今の段階では、問題を素早く解くよりも、よく見る習慣を身につけなければなりません.
質問する
地球温暖化で北極氷山が溶けている.図1に示すように、氷山を2次元アレイに表示します.氷山の各部分の高さ情報は,配列された各セルに正の整数として格納される.氷山以外の海に対応する格には0が格納されている.図1では、スペースはすべてゼロで埋め込まれていると思います.
図1.行数5、列数7の2 Dアレイの氷山の高さ情報を格納します.
氷山の高さは海水との接触が多い場所でより速く減少するため、配列中の氷山の各部分に対応する格子の高さは毎年、格子の中で東西南北4方向に付着する0の格子の個数を減少させる.ただし、各セルに格納される高さは0より小さくなりません.海水は湖水のように氷山に囲まれているかもしれない.従って、図1の氷山は、図2に示すように1年後に変形する.
図3は、図1の氷山の2年後の変化を示す.2 D配列では,東西南北方向の格子が互いに接続されている.したがって、図2の氷山は1つであり、図3の氷山は3つに分かれている.
氷山が1つ与えられた場合、プログラムを作成して、この氷山が2つ以上分離された最初の時間(年)を求めます.図1の氷山について、答えは2です.全てが溶けるまで2つ以上離さないと、プログラムは0を出力します.
入力
1行目では、2つの整数NとMは、2次元配列の行数と列数を表すスペースで区切られます.NとMは3以上300以下である.次のN行では、各行の間にスペースがあり、M個の整数は配列の各行を表します.各グリッドの値は0以上10以下です.配列では、氷山が占める格の個数、すなわち1以上の整数が占める格の個数が10000以下である.配列の最初の行と最後の行と最後の列は常に0で埋め込まれます.
しゅつりょく
1行目は氷山分離の最初の時間(年)を出力する.氷山が溶けるまで分離していない場合は0を出力します.
正しいコード
#include<bits/stdc++.h>
#define endl '\n'
int dy[] = {-1, 1, 0, 0};
int dx[] = {0, 0, -1, 1};
using namespace std;
int m,n;
bool bfs(vector<vector<int>>& v,vector<vector<bool>>& c, int y, int x)
{
if(y>=m || x>=n || y<0 || x<0) return false;
if(c[y][x]) return false;
c[y][x]=true;
return true;
}
int main()
{
pair<int,int> pos;
cin >> m >> n;
vector<vector<int>> v(m,vector<int> (n,0));
vector<vector<bool>> c(m,vector<bool> (n,0));
vector<vector<int>> czero(m,vector<int> (n,0));
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
cin >> v[i][j];
}
}
queue<pair<int,int>> q;
int cnt = -1;
bool check = true;
while(check)
{
cnt++;
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
czero[i][j]=0;
if(v[i][j]>0)
{
pos.first = i;
pos.second = j;
check = false;
}
else c[i][j]=true;
}
}
if(check) break;
q.push({pos.first,pos.second});
while(!q.empty())
{
for(int i=0; i<4; i++)
{
if(bfs(v, c , q.front().first+dy[i], q.front().second+dx[i]))
{
q.push({q.front().first+dy[i],q.front().second+dx[i]});
}
}
q.pop();
}
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(!c[i][j])
{
cout << cnt << endl;
return 0;
}
c[i][j]=false;
if(v[i][j]>0)
{
for(int k=0; k<4; k++)
{
if(v[i+dy[k]][j+dx[k]]<=0) czero[i][j]++;
}
}
}
}
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(czero[i][j]>0)
v[i][j]-=czero[i][j];
}
}
check = true;
}
cout << 0 << endl;
return 0;
}
解答と思考過程
すぐに問題を解決したいだけで、多くの間違いを犯した.
乱編
pop
は行われていなかったため、無限循環になり、氷山周辺の水の量を把握していないため、より速く減少したため、ミスが発生した.私の今の段階では、問題を素早く解くよりも、よく見る習慣を身につけなければなりません.
Reference
この問題について([アルゴリズム]BOJ 2573(氷山)), 我々は、より多くの情報をここで見つけました https://velog.io/@whddnjs5167/알고리즘-BOJ2573빙산テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol