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!
Search 1/2
By rilak1328
Search 1/2
- 863