題目鏈結。題目大意:給定迷宮的地圖,起點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 彼此以空格分隔。輸出描述 可能有多組測試資料,對於每組資料,按照要求排序後輸出,由空格分隔。測...