ACM寒假集訓

2021-10-17 18:44:55 字數 3004 閱讀 5132

出自–南昌理工學院acm集訓隊

什麼是dfs?

void dfs(狀態 a)

1.判斷狀態是否合法。合法繼續執行,否則則回到上次呼叫

2.先下走一層,也就是呼叫dfs(a+▲)

void

dfs(

)//引數用來表示狀態

if(越界或者是不合法狀態)

return;if

(特殊狀態)

//剪枝

return

;for

(擴充套件方式)

}}

完整的節點的遍歷順序如下(節點上的的藍色數字代表)

話不多說,上例題

全排列(入門引導)

輸出n個數的全排列

如 1,2,3組成的全排列

123132

213231

312321

對於這個問題,我們會直接想到直接列舉,emmmm,就是直接寫n重for迴圈

還有就是stl庫里有乙個全排列函式next_permutation

用遞迴的來想這個問題,以1,2,3,4為例

如果第乙個數固定為1的話

後面就跟著2,3,4的全排列——所以就是相當於是原問題的子問題的求解

考慮用遞迴解決

void

dfs(已經固定了前k-

1個數剩下的數的全排列,是哪k-

1個數通過標記該數字用沒用過來顯示,當前這一步的任務就是把第k個數放上去)

else

for(

int i=

1; i<=n; i++

)}

所以**可以寫成

#include

using

namespace std;

const

int maxn=

3e5+7;

int a[maxn]

;bool vis[maxn]

;//標記陣列,看這個位置上的數有沒有用過

int n;

void

dfs(

int depth)

for(

int i=

1;i<=n;i++)}

}int

main()

return0;

}

在上一道例題

p1219 [usaco1.5]八皇后 checker challenge

題目描述

乙個如下的 6×6 的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行、每列有且只有乙個,每條對角線(包括兩條主對角線的所有平行線)上至多有乙個棋子。

上面的布局可以用序列 2 4 6 1 3 5 來描述,第 i 個數字表示在第 i 行的相應位置有乙個棋子,如下:

行號 1 2 3 4 5 6

列號 2 4 6 1 3 5

這只是棋子放置的乙個解。請編乙個程式找出所有棋子放置的解。

並把它們以上面的序列方法輸出,解按字典順序排列。

請輸出前 3 個解。最後一行是解的總個數。

輸入格式

一行乙個正整數 n,表示棋盤是 n×n 大小的。

輸出格式

前三行為前三個解,每個解的兩個數字之間用乙個空格隔開。第四行只有乙個數字,表示解的總數。

輸入輸出樣例

輸入 #1

6輸出 #1

2 4 6 1 3 5

3 6 2 5 1 4

4 1 5 2 6 3

4說明/提示

【資料範圍】

對於 100% 的資料,6≤n≤13。

題目翻譯來自nocow。

usaco training section 1.5

題目大意

乙個 n×n 的棋盤,每行,每列有且只有乙個,每條對角線上至多只有乙個棋子

上**,嘿嘿

#include

typedef

long

long ll;

using

namespace std;

int n;

//n*n的格仔

int sum=0;

//解的總數

int vis[

1000

],l[

1000

],r[

1000];

//vis陣列表示的是列,l陣列表示左下到右上的對角線,r表示的是左上到右下的對角線

int a[

1000];

//a陣列表示的是行

void

dfs(

int depth)

sum++

;//記錄解的總數

return;}

for(

int i=

1;i<=n;i++)}

}int

main()

注意對角線r[i-depth]後面必須加上乙個n,因為i-depth可能為負數,那麼陣列就會出錯,所以將整體向右偏移n個單位(座標偏移不會影響我們需要達到的目的),將所有可能變成正數;(因為i-depth的最小值是-n+1,所以加上乙個n就一定會變成乙個正數)

可以先考慮六個皇后(即6*6網格),再將6改為n,並且輸入n,就可以得出6到13個皇后的解了

ACM寒假集訓 6

貪心演算法 又稱貪婪演算法 是指,在對問題求解時,總是做出在當前看來是最好的選擇。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,也就是說,不從整體最優上加以考慮,演算法得到的是在某種意義上的區域性最優解。貪心演算法一般按如下步驟進行 建立數學模型來描述問題。把求解的問題分成若干個...

ACM寒假集訓 7 dp(動態規劃)

將待求解問題分解成若干個子問題 經典三角問題 記憶陣列 intmaxsum int i,int j int main void cout maxsum 1 1 return0 由於遞迴會導致重複計算,使得時間複雜度變高,所以上面的記憶陣列用來儲存結果。一般的遞迴都可以用陣列,就是遞推寫出來 incl...

2013寒假ACM集訓 最小生成樹

普里姆演算法 稠密圖 克魯斯卡爾演算法 稀疏圖 1.prime 演算法 貪心 集合加點 2.kruskal演算法 並查集 加邊 思想是加 點,在邊比較多的情況下,用prime。思路 先找 任意一點到其他的點的 最短距離,再找 這個點和剛才的點 到其他的點的最短距離,依次重複 最小生成樹 prime模...