【搜索】C052_LG_奇怪的電梯(一維 bfs)

一、Problem

在這裏插入圖片描述

5 1 5
3 3 1 2 5

3

二、Solution

方法一:bfs

  • 每一層有 [1,Ki][1, K_i] 種選擇。
  • 如果按向上的按鈕,那麼不需要判斷邊界,因爲電梯可以按停。
  • 如果按向下的按鈕,那麼可提前阻斷到達第 1 層以下的層數。

WA 之 30/100…

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		int N, S, E, K[], maxn = 20000+5;
		int bfs() {
			Queue<Pos> q = new ArrayDeque<>();
			q.add(new Pos(S, 0));
			boolean[] vis = new boolean[maxn];
			while (!q.isEmpty()) {
				Pos t = q.poll();
				if (t.id == E) 
					return t.s+1;
				for (int k = 0; k < 2; k++) {
					if (k == 0) {
						for (int j = 1; j <= K[t.id]; j++) {
							int tt = t.id + j;
							if (vis[tt]) 
								continue;
							q.add(new Pos(tt, t.s+1));
							vis[tt] = true;
						}
					} else {
						for (int j = 1; j <= K[t.id]; j++) {
							int tt = t.id - j;
							if (tt <= 0 || vis[tt])
								continue;
							q.add(new Pos(tt, t.s+1));
							vis[tt] = true;
						}
					}
				}
			}
			return -1;
		}
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			N = sc.nextInt(); S = sc.nextInt(); E = sc.nextInt();
			K = new int[N+1];
			for (int i = 1; i <= N; i++) K[i] = sc.nextInt();
			int res = bfs();
			System.out.println(res);
		}
		class Pos {
			int id, s;
			Pos(int id, int s) {this.id = id; this.s = s;}
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

邏輯經修改後:

  • 就是水題一道,不必考慮那麼多,直接上或者下 K[i]K[i] 就行。
  • 再加上剪枝,跳過 Ki=0K_i = 0 的層,避免不必要的遍歷。
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		int N, S, E, K[], maxn = 500+5, dir[] = {1, -1};
		int bfs() {
			Queue<Pos> q = new ArrayDeque<>();
			q.add(new Pos(S, 0));
			boolean[] vis = new boolean[maxn];
			while (!q.isEmpty()) {
				Pos t = q.poll();
				if (t.id == E) 
					return t.s;
    			for (int k = 0; k < 2; k++) {
    			    if (K[t.id] == 0)
    			        continue;
    			    int tt = t.id + K[t.id] * dir[k];
    				if (tt <= 0 || tt > N || vis[tt]) 
    					continue;
    				q.add(new Pos(tt, t.s+1));
    				vis[tt] = true;
    			}
			}
			return -1;
		}
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			N = sc.nextInt(); S = sc.nextInt(); E = sc.nextInt();
			K = new int[500+5];
			for (int i = 1; i <= N; i++) K[i] = sc.nextInt();
			int res = bfs();
			System.out.println(res);
		}
		class Pos {
			int id, s;
			Pos(int id, int s) {this.id = id; this.s = s;}
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

複雜度分析

  • 時間複雜度:O(....)O(....)
  • 空間複雜度:O(...)O(...)

總結一下細節:

  • 我根本不明白出題人搞個其他兩個 開,關 按鈕有何作用,這不誤人子弟嗎?既然可以挺,那爲什麼不一層一層上/下,然後按停。再者,當有可能到達 E 層以外的,也算對啊,因爲可以停…
  • ki=0k_i = 0 的層直接跳過,不必再次計算了…
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章