双端队列 BFS + Chamber of Secrets CodeForces - 173B
題意:
一個 n×mn\times mn×m 的圖,現在有一束激光從左上角往右邊射出,每遇到 ‘#’,你可以選擇光線往四個方向射出,或者什么都不做,問最少需要多少個 ‘#’ 往四個方向射出才能使光線在第 n 行往右邊射出。
題目:
“The Chamber of Secrets has been opened again” — this news has spread all around Hogwarts and some of the students have been petrified due to seeing the basilisk. Dumbledore got fired and now Harry is trying to enter the Chamber of Secrets. These aren’t good news for Lord Voldemort. The problem is, he doesn’t want anybody to be able to enter the chamber. The Dark Lord is going to be busy sucking life out of Ginny.
The Chamber of Secrets is an n?×?m rectangular grid in which some of the cells are columns. A light ray (and a basilisk’s gaze) passes through the columns without changing its direction. But with some spell we can make a column magic to reflect the light ray (or the gaze) in all four directions when it receives the ray. This is shown in the figure below.
The left light ray passes through a regular column, and the right ray — through the magic column.
The basilisk is located at the right side of the lower right cell of the grid and is looking to the left (in the direction of the lower left cell). According to the legend, anyone who meets a basilisk’s gaze directly dies immediately. But if someone meets a basilisk’s gaze through a column, this person will get petrified. We know that the door to the Chamber is located on the left side of the upper left corner of the grid and anyone who wants to enter will look in the direction of its movement (in the direction
of the upper right cell) from that position.
This figure illustrates the first sample test.
Given the dimensions of the chamber and the location of regular columns, Lord Voldemort has asked you to find the minimum number of columns that we need to make magic so that anyone who wants to enter the chamber would be petrified or just declare that it’s impossible to secure the chamber.
Input
The first line of the input contains two integer numbers n and m (2?≤?n,?m?≤?1000). Each of the next n lines contains m characters. Each character is either “.” or “#” and represents one cell of the Chamber grid. It’s “.” if the corresponding cell is empty and “#” if it’s a regular column.
Output
Print the minimum number of columns to make magic or -1 if it’s impossible to do.
Examples
Input
3 3
.#.
…
.#.
Output
2
Input
4 3
##.
…
.#.
.#.
Output
2
Note
The figure above shows the first sample test. In the first sample we should make both columns magic. The dragon figure represents the basilisk and the binoculars represent the person who will enter the Chamber of secrets. The black star shows the place where the person will be petrified. Yellow lines represent basilisk gaze moving through columns.
分析:
1.此題目正解不是 0-1 BFS 但是適用 0-1 BFS 可以不需要思考過程,賽時許多大佬都是這么做的。
2.做法很簡單,一個方向射出不需要花費(0),而往四個方向射出需要花費(1),然后直接來就可以了。
3.復習雙端隊列deque
std::deque 是 STL 提供的 雙端隊列 數據結構。能夠提供線性復雜度的插入和刪除,以及常數復雜度的隨機訪問。
- 構造函數
參見如下代碼(假設你已經 using 了 std 命名空間相關類型):
- 元素訪問
與 vector 一致,但無法訪問底層內存。其高效的元素訪問速度可參考實現細節部分。
| at() | 返回容器中指定位置元素的引用,執行越界檢查,常數復雜度。 |
| operator[] | 返回容器中指定位置元素的引用。不執行越界檢查,常數復雜度。 |
| front() | 返回首元素的引用。 |
| back() | 返回末尾元素的引用。 |
- 元素增刪及修改
與 vector 一致,并額外有向隊列頭部增加元素的函數。
| clear() | 清除所有元素 |
| insert() | 支持在某個迭代器位置插入元素、可以插入多個。復雜度與 pos 與兩端距離較小者成線性。 |
| erase() | 刪除某個迭代器或者區間的元素,返回最后被刪除的迭代器。復雜度與 insert 一致。 |
| push_front() | 在頭部插入一個元素,常數復雜度。 |
| pop_front() | 刪除頭部元素,常數復雜度。 |
| push_back() | 在末尾插入一個元素,常數復雜度。 |
| pop_back() | 刪除末尾元素,常數復雜度。 |
| swap() | 與另一個容器進行交換,此操作是 常數復雜度 而非線性的。 |
- deque 的實現細節
deque 通常的底層實現是多個不連續的緩沖區,而緩沖區中的內存是連續的。而每個緩沖區還會記錄首指針和尾指針,用來標記有效數據的區間。當一個緩沖區填滿之后便會在之前或者之后分配新的緩沖區來存儲更多的數據。
AC代碼:
#include<stdio.h> #include<string.h> #include<deque> #include<iostream> using namespace std; const int M=1e3+10; const int inf=0x3f3f3f3f; int n,m; char mp[M][M]; int f[M][M][10]; int c[4][2]= {1,0,-1,0,0,1,0,-1}; deque<int>q; void Add_front(int x,int y,int dir,int step) {if(step<f[x][y][dir]){q.push_front(dir);//放在首位的需要倒著放入q.push_front(y);q.push_front(x);f[x][y][dir]=step;} } void Add_back(int x,int y,int dir,int step) {if(step<f[x][y][dir]){q.push_back(x);q.push_back(y);q.push_back(dir);f[x][y][dir]=step;} } int main() {cin>>n>>m;for(int i=0; i<n; i++)cin>>mp[i];for(int i=0; i<n; i++)for(int j=0; j<m; j++)for(int k=0; k<4; k++)f[i][j][k]=inf;Add_front(n-1,m-1,3,0);while(!q.empty()){int x=q[0];int y=q[1];int dir=q[2];q.pop_front();q.pop_front();q.pop_front();int xx=x+c[dir][0];int yy=y+c[dir][1];if(xx>=0&&yy>=0&&xx<n&&yy<m)Add_front(xx,yy,dir,f[x][y][dir]);if(mp[x][y]=='#'){for(int i=0; i<4; i++){if(i!=dir)Add_back(x,y,i,f[x][y][dir]+1);}}}if(f[0][0][3]==inf)cout<<"-1"<<endl;elsecout<<f[0][0][3]<<endl;return 0; }總結
以上是生活随笔為你收集整理的双端队列 BFS + Chamber of Secrets CodeForces - 173B的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 巫师3怒气爆发怎么用
- 下一篇: 玩家用英伟达滤镜玩原神玩家用英伟达滤镜玩