itint5 直角路線遍歷棋盤

2022-04-11 04:02:23 字數 1539 閱讀 3732

這題一開始直接用暴力的dfs來做,果然到25的規模就掛了.

vectorvisited(50, false);

vector> vec_row(50);

vector> vec_col(50);

bool findpath(vector&x, vector&y, int idx, int depth, int direction)

}} else }}

visited[idx] = false;

return false;

}//如果存在滿足條件的遍歷,返回true,否則返回false

bool existpath(vector&x, vector&y)

for (int i = 0; i < k; i++)

}return false;

}

正確的做法是轉化成尤拉迴路:

這題可以直接轉換為尤拉迴路(路徑)問題,這樣,如果有解的時候要輸出遍歷路徑的時候,也比較好辦了。

具體的轉換方式為:n,m的棋盤,建乙個包含n+m個頂點的圖g(為了方便說明,類似二分圖將其分為兩列,左邊n個頂點,右邊m個頂點,分別代表n行和n列)。對於目標格仔(i,j),左邊第i個頂點和右邊第j個頂點連一條邊。最後的問題其實就是問轉換之後的圖g是否存在尤拉尤拉迴路或者尤拉路徑。

證明:相鄰兩步為直角,其實就是從某一行變到某一列。訪問圖g中的一條邊,意味著訪問棋盤中的乙個目標點。由於圖g中的邊只連線左邊的點(代表某一行)和右邊的點(代表某一列),因此訪問一條邊就意味著從某一行變到了某一列,也就是轉直角了。

所以問題變為能否從一點出發訪問g中的所有邊有且僅有一次。這個就是尤拉迴路問題了。

所以尤拉路徑是:1.連通;2.奇點為2,為0時是尤拉迴路。

這裡的連通我用並查集來做。注意寫並查集的merge時,要先找到根,再merge。

vectordjset;

int find(int i)

djset[i] = x;

return x;

}void merge(int i, int j)

//如果存在滿足條件的遍歷,返回true,否則返回false

bool existpath(vector&x, vector&y)

for (int i = 0; i < y.size(); i++)

int count = 0;

for (int i = 0; i < axis.size(); i++)

if (count != 0 && count != 2) return false;

djset.resize(x.size());

for (int i = 0; i < djset.size(); i++)

// 判斷連通性

for (int i = 0; i < x.size(); i++) }}

for (int i = 0; i < y.size(); i++) }}

for (int i = 0; i < x.size(); i++)

}return true;

}

itint5 擺放視窗

一種做法是 把矩形所佔的方格都設為 1,就是個最大子矩陣和問題。複雜度o w 2 h 或o w h 2 空間w h 猜想應用場景是 電腦螢幕上已經有了n個聊天框,新建乙個聊天框,放在螢幕的哪個位置最好。客戶端計算的話,空間複雜度太高的演算法應該是沒法實際應用的。這種方法oj也會空間超出。另一種做法 ...

itint5 字串匹配

用hash來做,目前為止做到最好也是case16超時 20w的規模 即使分桶也超時。注意計算hashcode時,a 要算成1,否則如果 a 為0,那麼 aa 和 a 是一樣的。下面是超時的 define bucket 65535 define ulong long long vector uset ...

5 走自己的路

親歷感悟 只有走自己的路,結合自身的實際,確立清晰地 最適合自己的目標,才能使自己的努力獲得最大的回報,最終實現自己的人生目標。當我們每天為了自己的目標忙碌奔波的時候,是否曾有過深深的困惑 為什麼我們如此忙碌,目標卻仍然那麼模糊而又遙遠?是否曾有過沮喪的心情,我缺乏成功的天賦?還是我總是那麼時運不濟...