P4554 小明的遊戲 洛谷 雙端佇列BFS

2022-06-15 12:00:10 字數 1500 閱讀 2038

最近沒有更新部落格,全是因為英語,英語太難了qwq

洛谷春令營的作業我也不會(我是弱雞),隨機跳了2個題,難度不高,還是講講吧,學學新演算法也好(可以拿來水部落格)

第一題就是這個小明的遊戲

小明最近喜歡玩乙個遊戲。給定乙個 n×m的棋盤,上面有兩種格仔#和@。遊戲的規則很簡單:給定乙個起始位置和乙個目標位置,小明每一步能向上,下,左,右四個方向移動一格。如果移動到同一型別的格仔,則費用是0,否則費用是1。請程式設計計算從起始位置移動到目標位置的最小花費。

輸入格式

輸入檔案有多組資料。

輸入第一行包含兩個整數n,m,分別表示棋盤的行數和列數。

輸入接下來的n行,每一行有m個格仔(使用#或者@表示)。

輸入接下來一行有四個整數x1, y1, x2, y2

分別為起始位置和目標位置。

當輸入n,m均為0時,表示輸入結束。

輸出格式

對於每組資料,輸出從起始位置到目標位置的最小花費。每一組資料獨佔一行。

看起來像個廣搜,但是我們仔細想想的話會發現,這玩意是有權值的,可能我走100格用的費用比你走一格用的都少,在最少費用的要求下,顯然不能用普通的廣搜。

廣搜的特點是把所有能走到的點全加進佇列,為什麼會用這種演算法呢?,因為每走一步就需要一點費用的情況下,這樣走花費最少。

於是,我們可以想出乙個主意,我們讓佇列雙開口,把花費小的放在前面,花費大的放後面豈不美哉。但有的同學可能會疑惑(其實只有我),這樣的話不是要手打堆排?不不不,裡面最多有2種數,因為我們去檢視大數的情況前先要看小數的情況,小數只能變成自己或者自己+1,如果是自己+1,變成大數,放在最後。如果不是,放在前面再來一遍。所以這個佇列裡只會有2種數。不用擔心排序的問題。

再來幾個小提示就貼**了:

1、佇列記得清空

2、記得標記來過沒

3、有個東西叫deque,deque支援高效插入和刪除容器的頭部和尾部元素,因此也叫做雙端佇列(我用的就是這個)

#include#include#includeusing namespace std;

char sz[505][505];

long long a[500][500];

long long n,m,qx,qy,zx,zy;

long long fx[4]=;//控制移動的陣列

long long fy[4]=;

dequeqz;//3個雙端佇列

dequexd;

dequeyd;

long long x,y,z;

void sddl()

}scanf("%lld%lld%lld%lld",&qx,&qy,&zx,&zy);

a[qx][qy]=1;//省一下

xd.push_front(qx);//這個是插入到頭部的意思

yd.push_front(qy);

qz.push_front(0);

sddl();

}return 0;

}

陽光健康,就到這裡吧。

P4554 小明的遊戲

小明的遊戲就是玩棋盤?和這道題有啥區別啊。如果不加多組測試資料,這道題可能還沒那道題難。好了,吐槽結束 首先還是按照比較常規的思路來想,上下左右都已經寫出來了,dfs和bfs沒得跑,蒟蒻不太會處理bfs,因為實在沒有想出來怎麼寫,所以第一次我寫的是dfs 記憶化搜尋,水了60分,因為dfs本來就慢,...

P4554 小明的遊戲

每個點向它旁邊的點連邊,相同dis為0,不同為1。n 3,m 3每個點的標號如下 1 2 3 4 5 6 7 8 9 這樣安排標號唯一,標號計算公式 i 1 m j 連邊時判斷一下邊界,因為題目預設座標是從 0,0 開始,所以方便做題,將讀入的起點和終點座標都加1。然後跑個最短路就可以了 inclu...

洛谷P1714 切蛋糕(雙端佇列)

題意 給定n個數,從中選擇最多m個連續的數,使得這些數的和最大 輸入 第一行n,m。第二行,n個整數 輸出 輸出所選擇的數的和 題解 這道題第一感覺肯定是字首和,但是這裡有乙個難點,就是最多是選擇m個連續的數,而不是一定是m個數,所以這裡面的複雜度就會有點高 如果暴力的話 暴力就是找到第i個數的前面...