Search

.part1/2



Intro





基礎

暴力搜尋 = 窮舉




Try and Fail




因為包含所有可能性

基本上不用證明



Focus

搜索模式與方法

搜索範圍 (剪枝)


Search範圍


暴力搜索

DFS 與 BFS

Binary Search

剪枝



今天我想講的


用DFS做完全搜索



Complete

Search




窮舉所有可能性




1. Range

用最小的範圍涵蓋你想找的資訊


Q

給一個數 N

(2 <= N <= 100,000)

請判斷N是不是質數

(經典技巧)

偽! Answer


賭人品用費馬小定理




聽說錯的機率很小

A

列舉所有i  (i 的 range 是) 2<= i < N

如果(Search)找到 N%i = = 0

那N不是質數

Time Complexity

(時間複雜度)



O(N)

Q

承上題

改成 T 筆詢問 (1<=T<=10000)

或是

條件改成 N >= 1,000,000,000


Time

1,000,000,000

=TLE

A


賭人品用費馬小定理

A

列舉量到根號N就可以了


WHY?

跪求證明


Bool isprime(long long x){

     for(int i=2; i*i<=x ; i++)

         if (x % i== 0) return false;

  return true;

}




2.Search 的對象

選一個最容易處理的對象

Q

給你一張N * N的圖 (N<=1000)

每一格會是 1 或 0

問有多少個由 1 組成的實心正方形 (HOJ p116)

ex

1 1 1  1 1 1

101  1 1 1

1 1 1  1 1 1


         8個  14個(9+4+1)

Think!


找每種Size的正方形

Time


1*1 的正方形 -> N*N個位置 * (1*1)次比對

2*2正方形 -> (N-1)*(N-1)個位置 * (2*2)次比對

3*3的正方形

...

500*500的正方形 => 500*500*500*500

...


感覺就會爛掉(接近N^4)

A


等教了DP再說吧XD




我只是想說

很多時候無腦暴搜註定會爛掉。

Q

HOJ p027 數字拼盤

參考左圖

我們可以把2往下移

或是把3往右移

給一個盤面,判斷能不能在20步移動內

將盤面移動成

分析


每一步可能有2 / 3 / 4種可能性

20步而已,不多


大概 3 ^ 20


TLE

Thinking



不走回頭路

AC



就這樣



我只是想要說

多想一步 生命會更美好



Complete Search

HOW  TO






列舉一個維度




for(起點 終點 下一步)

這大家都會




列舉兩個維度



for(i = 1;i < n;i++)

for(j = 1;j < m;j++)




三個維度...



在九宮格中填入1~9

直行/橫列/對角 的 合要一樣

for(a = 1~9)

for(b = 1~9) if(b != a)
for(c = 1~9) if(c!=b && c!=a)
for(d = 1~9) if(d!=a && d!=b && d!=c)
for(e = 1~9) if(e!=a && e!=b &&......................)
for(f = 1~9) if(............................................................)
for(g = 1~9) if(......................................................................)
for(h = 1~9) ..........................................................................
for(j = 1~9)............................................................................


WHAT?




cout << "fuck";

//這是IOI rank1 的霸氣


1.Range

2.對象

3. 方法


遞迴暴搜

(DFS走訪答案圖)


第一格 1  2  3  4  5  6  7  8  9

第二格 12  13  14  15  16  17  18  19       21  23  24  25  26........



乾 看不懂拉
第三格 123 124 125 126....




如果只有1~3

132

213

231

312

321

1

2

3

12

13

21

23

31

32

123

DFS 四步驟


1.  Final -> return;
2. Do Something
3. Next Level
4. Undo Something





int  array[4];

bool used[4];

DFS




void DFS(int level){}

1. Final -> return;



if(level == 4) return;

2. Do something


填空

for(int i=1;i<=3;i++)
if( !used[i]){
array[level] = i;
used[i] = true;
}

3. Next Level



DFS(level + 1);

4. Undo something



used[i] = false;

array[level] = 0;

Combine


void DFS(level){
if( level == 4) return;

for(int i=1;i<=3;i++)  if(!used[i]){
used[i] = true ;
array[level] = i ;
DFS(level+1);
used[i] = false;
}

}

How DFS work?

132

213

231

312

321

1

2

3

12

13

21

23

31

32

123

How DFS work?

132

213

231

312

321

1

2

3

12

13

21

23

31

32

123

How DFS work?

132

213

231

312

321

1

2

3

12

13

21

23

31

32

123

How DFS work?

132

213

231

312

321

1

2

3

12

13

21

23

31

32

123

How DFS work?

132

213

231

312

321

1

2

3

12

13

21

23

31

32

123

How DFS work?

5

8

10

14

15

1

6

11

2

4

7

9

12

13

3



HOW TO DFS

Just CODING!

Made with Slides.com