奇偶減支的使用

2021-09-02 13:54:46 字數 1707 閱讀 1189

題目鏈結。題目大意:給定迷宮的地圖,起點s終點d和限制,d是一扇門,會在t時刻內開啟,只有當d開啟並且dog到達該點才能成功的逃脫,否則無法逃脫。給出相關的引數,判斷dog是否可以逃脫。

看完之後發現這顯然是乙個dfs搜尋的題目,我們當前點進行四個方向的搜尋,判斷步數和時間的關係即可。但是會發現程式超時,那麼說明乙個問題,我們的減支的力度不夠,要從別的方面思考該如何進行減支。看到這個題和一般的題有一點小小的區別,一般的迷宮搜尋都是在規定時間內出去即可,但是這裡需要在準確的時間到達,因為題目中要求每乙個點只能到達一次並且不能停留。所以在這裡最短路不一定是最正確的選擇。我們來思考dfs的減支

(1)t時刻內到達出口,遞迴結束

(2)t時刻內沒有達到出口,遞迴也要結束

(3)小於t時刻內達到出口,這個時候沒用,因為門沒有開,所以也沒用。

使用這三個減支的規則來減支,提交發現依然是超時。這個時候就開始懷疑人生了,難道這個題不是dfs?不會吧,顯然是的啊。說明我們還有一些地方的減支沒有考慮到。繼續向下分析:這個題目很大的特點就是在迷宮中需要使用恰好t秒,不能多也不能少。那麼其實我們可以發現一些二東西。假設出口d的座標是在x,y當前的座標點是在px,py.那麼最少的時間肯定是兩點之間的哈密頓距離。如果這時的時間已經不足,那麼顯然也是不能到達的,因為最短的時間已經不允許出去。ok,這個時候我們其實有得到了乙個很重要的減支,其實我們在每一層的dfs都加乙個這樣的判斷,那麼就可以起到很大的作用。加上這個減支之後依然是超時,what?這nm還超,行吧,終極大招,奇偶減支。結合**來說明:

#include #include #include char map[10][10]; //7*7

int book[10][10];

int p, q, n, m, t, flag;

int next[4][2] = , , , }; //右下左上

void dfs(int x, int y, int step)

if (step >= t) return; //!!!剪枝 超時或沒走到

temp = t - step - abs(p - x) - abs(q - y);//這個

if (temp < 0 || temp & 1) return;

//剪枝:如果剩餘的步數不足以走到出口,且必須是偶數,偶-偶=偶,奇-奇=偶

for (i = 0; i < 4; i++)

}return;

}int main()

else if (map[i][j] == 'd')

else if (map[i][j] == 'x')

wall++;

}getchar();

}if (t > n*m - wall) printf("no\n");

//abs(p-startx)+abs(q-starty)為到達終點的最少步數

else if (abs(p - startx) + abs(q - starty) >= t && (startx + starty + p + q + t) % 2 == 1) printf("no\n");

//偶數點到偶數點(座標xy之和)需要走偶數次,奇數到奇數也要走偶數次。

else

}return 0;}/*

這裡回溯的原因:在搜尋整個迷宮的時候,對於當前點:進行四個方向的搜尋,dx=x+nex[i][j].假設這個點已經完成搜尋

那麼需要轉移搜尋中心,所以這裡需要回溯

*/

使用定義判斷函式的奇偶性

判斷函式 f x ln x sqrt 的奇偶性。log mn log m log n 在 matlab 下面的 在 matlab 9.1.0.441655 r2016b 中測試通過 中輸入如下 x 0 0.01 10 semilogy x,log x 可以繪製出 y ln x 的影象 圖 1有影象可...

Verilog的奇偶分頻

這裡參考了兩個部落格,內容大體相同。但是要說一點,這兩個部落格在介紹奇數分頻時,都說了一段話 對於實現占空比為50 的n倍奇數分頻,首先進行上公升沿觸發進行模n計數,計數選定到某乙個值進行輸出時鐘翻轉,然後經過 n 1 2再次進行翻轉得到乙個占空比非50 奇數n分頻時鐘。再者同時進行下降沿觸發的模n...

整數的奇偶排序

題目描述 輸入10個整數,彼此以空格分隔。重新排序以後輸出 也按空格分隔 要求 1.先輸出其中的奇數,並按從大到小排列 2.然後輸出其中的偶數,並按從小到大排列。輸入描述 任意排序的10個整數 0 100 彼此以空格分隔。輸出描述 可能有多組測試資料,對於每組資料,按照要求排序後輸出,由空格分隔。測...