169. [USACO Feb07] 青銅蓮花池
★ 輸入檔案:bronlily.in 輸出檔案:bronlily.out 簡單對比
時間限制:1 s 記憶體限制:128 MB
譯 By CmYkRgB123
描述
Farmer John 建造了一個美麗的池塘,用於讓他的牛們審美和鍛煉。這個長方形的池子被分割成了 M 行和 N 列( 1 ≤ M ≤ 30 ; 1 ≤ N ≤ 30 ) 正方形格子的 。某些格子上有驚人的堅固的蓮花,還有一些岩石,其餘的只是美麗,純淨,湛藍的水。
貝茜正在練習芭蕾舞,她從一個蓮花跳躍到另一個蓮花,當前位於一個蓮花。她希望在蓮花上一個一個的跳,目標是另一個給定蓮花。她能跳既不入水,也不到一個岩石上。
令門外漢驚訝的是,貝茜的每次的跳躍像國際象棋中的騎士一樣:橫向移動M1(1 ≤M1 ≤ 30 ),縱向移動然後量M2 (1 ≤M2 ≤ 30 ;M1 ≠ M2 ) ,或縱向移動然後量M1,橫向移動M2。貝茜有時可能會有多達8個選擇的跳躍。
給定池塘的布局和貝茜的跳躍格式,請確定貝茜從從她的出發位置,到最終目的地,最小的跳躍次數,貝茜在給出測試資料一定可以跳到目的地。
輸入
- 第 1 行: 四個用空格隔開的整數: M, N, M1, M2
- 第 2..M + 1 行: 第 i + 1 行 有 N 個整數,表示該位置的狀態: 0 為水; 1 為蓮花; 2 為岩石; 3 為貝茜開始的位置; 4 為貝茜要去的目標位置.
輸出
- 第 1 行: 一個整數,從起始點到要去的位置,貝茜最小的跳躍次數。
範例輸入
4 5 1 21 0 1 0 13 0 2 0 40 1 2 0 00 0 0 1 0
範例輸出
2
輸入解釋
貝茜從第2行第1個位置開始,她的目標在第2行最右邊。幾個
輸出解釋
貝茜聰明地跳躍到了第1行第3個位置,然後就到了目的地。
基礎搜尋。
#include<cstdio>#include<queue>using namespace std;const int maxn =33;int map[maxn][maxn];struct node{ int x,y; int step;}s_pos;int m,n,m1,m2,step;int sx,sy,ex,ey;bool vis[maxn][maxn];bool check(int x,int y){ return x>=0&&x<m&&y>=0&&y<n;}void bfs(){ int dx[]={-m1,-m1,m1,m1,-m2,-m2,m2,m2}; int dy[]={m2,-m2,m2,-m2,m1,-m1,m1,-m1}; queue<node> q; s_pos.x=sx; s_pos.y=sy; s_pos.step=0; q.push(s_pos); vis[sx][sy]=true; while(!q.empty()){ node now = q.front();q.pop(); if(now.x==ex&&now.y==ey){ step=now.step;return; } for(int i=0;i<8;i++){ int nx=now.x+dx[i]; int ny=now.y+dy[i]; if(check(nx,ny)&&!vis[nx][ny]&&(map[nx][ny]==1||map[nx][ny]==4)){ node next = now; next.x=nx; next.y=ny; next.step++; q.push(next); vis[nx][ny]=true; } } }}int main(){ freopen("bronlily.in","r",stdin); freopen("bronlily.out","w",stdout); scanf("%d%d%d%d",&m,&n,&m1,&m2); for(int i=0;i<m;i++) for(int j=0;j<n;j++) scanf("%d",&map[i][j]); for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(map[i][j]==3){ sx=i;sy=j; } if(map[i][j]==4){ ex=i;ey=j; } } } bfs(); printf("%d\n",step); return 0;}