これがエンコーディングテスト-DFS/BFS 1
33266 ワード
DFSとBFSは典型的なブラウズアルゴリズムである.
DFSはスタックと再帰関数を用いて実現できる.
BFSはキューを用いて実現する.
今から実戦問題を確認してみましょう.
実戦問題冷凍飲料
DFSはスタックと再帰関数を用いて実現できる.
BFSはキューを用いて実現する.
今から実戦問題を確認してみましょう.
実戦問題冷凍飲料
質問の概要:
N、Mを受け入れ、N*Mサイズの配列に0と1を入力します.1はスペース、0はスペースです.これは総区間数を求める問題です.
この問題は典型的な探索アルゴリズム問題である.
BFSもDFSも使えますが、BFSアルゴリズムを使って実現してみました.
実装コード:import java.util.*;
import java.io.*;
class Node{
int x, y;
Node(int x,int y){
this.x = x;
this.y = y;
}
}
public class Main{
static int[][] cover;
static int[][] visited;
static int n ,m , cnt =0;
static int []dx = {0 ,0 ,-1 ,1};
static int []dy = {1 ,-1 ,0 ,0};
static Queue<Node>queue;
public static void bfs(int x ,int y) {
queue = new LinkedList<>();
queue.add(new Node(x,y));
visited[x][y] = 1;
while(!queue.isEmpty()) {
Node node = queue.poll();
for(int i = 0; i < 4; i++) {
int nx = node.x + dx[i];
int ny = node.y + dy[i];
if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if(cover[nx][ny] == 0 && visited[nx][ny] == 0) {
queue.add(new Node(nx,ny));
visited[nx][ny] = 1;
}
}
}
}
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
cover = new int[n][m];
visited = new int[n][m];
for(int i = 0; i < n; i++) {
String str = br.readLine();
for(int j = 0; j < m ; j++) {
cover[i][j] = str.charAt(j) -'0';
}
}
for(int i = 0;i < n ; i ++) {
for(int j = 0; j < m; j++) {
if(cover[i][j] == 0 && visited[i][j] == 0) {
bfs(i,j);
cnt ++;
}
}
}
System.out.println(cnt);
}
}
コードの説明:
まず入力をスキップしてbfsを理解します.bfsはまず隣接ノードを検査し,次に検査する.だからqueueを使って実現して、私も初めてbfsに触れたときに髪を結んだのを覚えています.しかし、構造を知ると、簡単に感じることができます.まず、配列値とアクセスするかどうかを確認します.両方が条件を満たしている場合は、bfs関数を実行します.bfs関数は次のようになります.
まず、値をキューに挿入し、while文を実行して、キューがすべて空になるまで値を繰り返します.Nodeという名前のclassを作成してxy値を保存するのが便利です重要なのは、問題で上下左右に整列して表示されるので、for文を4回回転させることです.そして、上下左右に移動する場合は、フレームから飛び出していないことを確認してください.また、条件が満たされている場合は、キューに再追加することに重点を置きます.
実戦問題.迷宮を探す
質問の概要:
N×Mサイズの長方形の迷宮には何匹もの怪物がいて、それを避けて逃げようとしています.現在位置は(1,1),迷路出口は(N,M)位置にあり,一度に1格移動可能である.モンスターがいる部分は0で、モンスターがいない部分は1で表示されます.迷宮はきっと逃げられる形で現れたに違いない.逃げるために移動しなければならない最小格子数を求める.セルを計算すると、開始セルと最後のセルが含まれます.
入力
第1行は2つの整数N,M(4<=N,M<=200)を与える.次のN行では,迷路の情報をそれぞれM個の整数(0または1)で与える.各数字には入力としてスペースが付いています.また、開始バーと最後のバーは常に1です.
しゅつりょく
1行目に最小移動格子数を出力します.
入力例5 6
101010
111111
000001
111111
111111
出力例10
実装コード:import java.util.*;
import java.io.*;
class Node{
int x, y;
Node(int x, int y){
this.x = x;
this.y = y;
}
}
public class main2 {
static int[][] map;
static int n ,m ,x ,y;
static int[] dx = {0 ,0 ,-1 ,1};
static int[] dy = {1 ,-1 ,0 ,0};
static Queue<Node>queue;
public static void bfs(int x ,int y) {
queue = new LinkedList<>();
queue.add(new Node(x ,y));
while(!queue.isEmpty()){
Node node = queue.poll();
for(int i = 0 ; i < 4 ;i++) {
int nx = node.x + dx[i];
int ny = node.y + dy[i];
if(nx < 0 || nx >= n || ny <0 || ny >= m) continue;
if(map[nx][ny] == 0) continue;
if(map[nx][ny] == 1) {
queue.add(new Node(nx,ny));
map[nx][ny] = map[node.x][node.y] + 1;
}
}
}
}
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
map =new int[n][m];
for(int i = 0 ;i < n; i++) {
String str = br.readLine();
for(int j = 0 ; j < m; j++) {
map[i][j] = str.charAt(j) -'0';
}
}
bfs(0,0);
System.out.println(map[n-1][m-1]);
}
}
コード解釈:迷宮脱出問題は典型的なbfs問題である.最短距離を求めるので,隣接値に移動する方法が必要である.絵で理解しよう
図:https://blog.hexabrain.net/269ブログから転送されます.
1が出発点だと思ってください.冷凍飲料問題とは異なり、冷凍飲料の区間が分かれているのでbfs関数を呼び出し続ける必要があるが、迷宮脱出問題はつながっているので、一度だけ呼び出すだけでよい.
さらに図に戻ると、3から4の部分があります.2つのブランチに分かれており,3に隣接するノードを探す場合は,移動可能なパスを前のノード値+1に設定するだけでよい.次にqueueに挿入し、マイナス記号を繰り返し、以前のノード値+1にします.
Reference
この問題について(これがエンコーディングテスト-DFS/BFS 1), 我々は、より多くの情報をここで見つけました
https://velog.io/@cse05091/이것이-코딩테스트다-DFSBFS-1
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import java.util.*;
import java.io.*;
class Node{
int x, y;
Node(int x,int y){
this.x = x;
this.y = y;
}
}
public class Main{
static int[][] cover;
static int[][] visited;
static int n ,m , cnt =0;
static int []dx = {0 ,0 ,-1 ,1};
static int []dy = {1 ,-1 ,0 ,0};
static Queue<Node>queue;
public static void bfs(int x ,int y) {
queue = new LinkedList<>();
queue.add(new Node(x,y));
visited[x][y] = 1;
while(!queue.isEmpty()) {
Node node = queue.poll();
for(int i = 0; i < 4; i++) {
int nx = node.x + dx[i];
int ny = node.y + dy[i];
if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if(cover[nx][ny] == 0 && visited[nx][ny] == 0) {
queue.add(new Node(nx,ny));
visited[nx][ny] = 1;
}
}
}
}
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
cover = new int[n][m];
visited = new int[n][m];
for(int i = 0; i < n; i++) {
String str = br.readLine();
for(int j = 0; j < m ; j++) {
cover[i][j] = str.charAt(j) -'0';
}
}
for(int i = 0;i < n ; i ++) {
for(int j = 0; j < m; j++) {
if(cover[i][j] == 0 && visited[i][j] == 0) {
bfs(i,j);
cnt ++;
}
}
}
System.out.println(cnt);
}
}
質問の概要:
N×Mサイズの長方形の迷宮には何匹もの怪物がいて、それを避けて逃げようとしています.現在位置は(1,1),迷路出口は(N,M)位置にあり,一度に1格移動可能である.モンスターがいる部分は0で、モンスターがいない部分は1で表示されます.迷宮はきっと逃げられる形で現れたに違いない.逃げるために移動しなければならない最小格子数を求める.セルを計算すると、開始セルと最後のセルが含まれます.
入力
第1行は2つの整数N,M(4<=N,M<=200)を与える.次のN行では,迷路の情報をそれぞれM個の整数(0または1)で与える.各数字には入力としてスペースが付いています.また、開始バーと最後のバーは常に1です.
しゅつりょく
1行目に最小移動格子数を出力します.
入力例
5 6
101010
111111
000001
111111
111111
出力例10
実装コード:import java.util.*;
import java.io.*;
class Node{
int x, y;
Node(int x, int y){
this.x = x;
this.y = y;
}
}
public class main2 {
static int[][] map;
static int n ,m ,x ,y;
static int[] dx = {0 ,0 ,-1 ,1};
static int[] dy = {1 ,-1 ,0 ,0};
static Queue<Node>queue;
public static void bfs(int x ,int y) {
queue = new LinkedList<>();
queue.add(new Node(x ,y));
while(!queue.isEmpty()){
Node node = queue.poll();
for(int i = 0 ; i < 4 ;i++) {
int nx = node.x + dx[i];
int ny = node.y + dy[i];
if(nx < 0 || nx >= n || ny <0 || ny >= m) continue;
if(map[nx][ny] == 0) continue;
if(map[nx][ny] == 1) {
queue.add(new Node(nx,ny));
map[nx][ny] = map[node.x][node.y] + 1;
}
}
}
}
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
map =new int[n][m];
for(int i = 0 ;i < n; i++) {
String str = br.readLine();
for(int j = 0 ; j < m; j++) {
map[i][j] = str.charAt(j) -'0';
}
}
bfs(0,0);
System.out.println(map[n-1][m-1]);
}
}
コード解釈:迷宮脱出問題は典型的なbfs問題である.最短距離を求めるので,隣接値に移動する方法が必要である.絵で理解しよう図:https://blog.hexabrain.net/269ブログから転送されます.
1が出発点だと思ってください.冷凍飲料問題とは異なり、冷凍飲料の区間が分かれているのでbfs関数を呼び出し続ける必要があるが、迷宮脱出問題はつながっているので、一度だけ呼び出すだけでよい.
さらに図に戻ると、3から4の部分があります.2つのブランチに分かれており,3に隣接するノードを探す場合は,移動可能なパスを前のノード値+1に設定するだけでよい.次にqueueに挿入し、マイナス記号を繰り返し、以前のノード値+1にします.
Reference
この問題について(これがエンコーディングテスト-DFS/BFS 1), 我々は、より多くの情報をここで見つけました https://velog.io/@cse05091/이것이-코딩테스트다-DFSBFS-1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol