UVALive 6888 Ricochet Robots bfs

 2023-12-06 阅读 28 评论 0

摘要:Ricochet Robots 題目連接: http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129726 Description A team of up-to four robots is going to deliver parts in a factory floor. The floor is organized as a rectangular grid where each robot

Ricochet Robots

題目連接:

http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129726

Description

A team of up-to four robots is going to deliver parts in
a factory floor. The floor is organized as a rectangular
grid where each robot ocupies a single square cell.
Each robot is represented by an integer from 1 to 4
and can move in the four orthogonal directions (left,
right, up, down). However, once set in motion, a robot
will stop only when it detects a neighbouring obstacle
(i.e. walls, the edges of the factory or other stationary
robots). Robots do not move simultaneously, i.e. only
a single robot moves at each time step.
The goal is to compute an efficient move sequence
such that robot 1 reaches a designed target spot; this
may require moving other robots out of the way or to
use them as obstacles for “ricocheting” moves.
Consider the example given above, on the right,
where the gray cells represent walls, X is the target
location and ?1 , ?2 mark the initial positions of two robots. One optimal solution consists of the six
moves described below.
?2
?1
X
?1 moved up.
?1
?2 X
?2 moved right, down and left.
?2 ?1
?1 moved down and left.
Note that the move sequence must leave robot 1 at the target location and not simply pass through
it (the target does not cause robots to stop — only walls, edges and other robots).
Given the description of the factory floor plan, the initial robot and target positions, compute the
minimal total number of moves such that robot 1 reaches the target position.

Input

The input file contains several test cases, each of them as described below.
The first line contains the number of robots n, the width w and height h of the factory floor in cells,
and an upper-bound limit ? on the number of moves for searching solutions.
The remaining h lines of text represent rows of the factory floor with exactly w characteres each
representing a cell position:
‘W’ a cell occupied by a wall;
‘X’ the (single) target cell;
‘1’,‘2’,‘3’,‘4’ initial position of a robot;
‘.’ an empty cell.
Constraints:
1 ≤ n ≤ 4
max(w, h) ≤ 10
w, h ≥ 1
1 ≤ ? ≤ 10

Output

For each test case, the output should be the minimal number of moves for robot 1 to reach the target
location or ‘NO SOLUTION’ if no solution with less than or equal the given upper-bound number of moves
exists.

Sample Input

2 5 4 10
.2...
...W.
WWW..
.X.1.
1 5 4 10
.....
...W.
WWW..
.X.1.

Sample Output

6
NO SOLUTION

Hint

題意

給你一個棋盤,棋盤上面有最多四個棋子,你的目標是把一號棋子走到X位置,你可以動棋子,棋子的話,只能往四個方向走,走必須走到底,除非碰到邊界或者墻,或者其他棋子。
讓你在l步以內輸出最小節,問你能不能。

題解:

一眼搜索題,但是究竟是dfs還是bfs呢?

他給你了個上界,所以一般就直接思考bfs了,而不是dfs

所以直接bfs莽一波就好了,沒啥好說的呢,剩下就是碼碼碼。

代碼

#include <bits/stdc++.h>
#define rep(a,b,c) for(int (a)=(b);(a)<=(c);++(a))
#define drep(a,b,c) for(int (a)=(b);(a)>=(c);--(a))
#define pb push_back
#define mp make_pair
#define sf scanf
#define pf printf
#define two(x) (1<<(x))
#define clr(x,y) memset((x),(y),sizeof((x)))
#define dbg(x) cout << #x << "=" << x << endl;
#define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
using namespace std;
const int maxn = 10 + 5;
const int mod = 100000;
int extra[8]={123,115,65147,233,6421,7361,73561,442};
int num,N,M,Limit,Up[maxn][maxn],Down[maxn][maxn],Lft[maxn][maxn],Rht[maxn][maxn],targetX,targetY;
char G[maxn][maxn];bool inmap(int x , int y){ return 1 <= x && x <= N && 1 <= y && y <= M; }int Got_Up(int x , int y){if(!inmap(x,y)||G[x][y]=='W') return 0;if(~Up[x][y]) return Up[x][y];return Up[x][y]=Got_Up(x-1,y)+1;
}int Got_Down(int x , int y){if(!inmap(x,y)||G[x][y]=='W') return 0;if(~Down[x][y]) return Down[x][y];return Down[x][y]=Got_Down(x+1,y)+1;
}
int GOt_Lft(int x , int y){if(!inmap(x,y)||G[x][y]=='W') return 0;if(~Lft[x][y]) return Lft[x][y];return Lft[x][y]=GOt_Lft(x,y-1)+1;
}
int Got_Rht(int x , int y){if(!inmap(x,y)||G[x][y]=='W') return 0;if(~Rht[x][y]) return Rht[x][y];return Rht[x][y]=Got_Rht(x,y+1)+1;
}struct Data{pair < int , int > p[4] ;int step ;int cal_hash(){int tot = 0  ;long long A = 0;rep(i,0,num-1){A += p[i].first * extra[tot ++ ];A += p[i].second * extra[tot ++ ];}if( A >= mod ) A %= mod;return (int)A;}Data( const pair < int , int > & a , const pair < int , int > & b , const pair < int , int > & c , const pair < int , int > & d , int sp ){ p[0]= a,p[1]=b,p[2]=c,p[3]=d,step=sp; }
};vector < Data > Judge[mod];
pair < int , int > base[4];
queue < Data > Q;void Try_Push( Data & np ){if(np.step > Limit) return ;int h = np.cal_hash();for(auto it : Judge[h] ){int ok = 1;rep(j,0,num - 1)if(it.p[j]!=np.p[j]){ok = 0 ;break;}if(ok) return ;}Q.push( np );Judge[h].pb(np);
}void Init(){for(int i = 0 ; i < mod ; ++ i) Judge[i].clear();
}int bfs(){while(!Q.empty()) Q.pop();Q.push( Data( base[0] , base[1] , base[2] , base[3] , 0 ));while(!Q.empty()){Data fq = Q.front() ; Q.pop();if( fq.p[0].first == targetX && fq.p[0].second == targetY ) return fq.step;if( fq.step == Limit ) continue;for(int idx = 0 ; idx <= num - 1 ; ++ idx ){// 準備移動第 idx 個pair < int , int > pos = fq.p[idx]; // 獲得初始位置//cout << "Come here " << endl;int x  = pos.first , y = pos.second;// 向上{pair < int , int > nxtpos = mp( pos.first - Up[x][y] , pos.second );rep(j,0,num - 1){if( fq.p[j].second == y && fq.p[j].first < pos.first && fq.p[j].first >= nxtpos.first  ){nxtpos.first = fq.p[j].first + 1;}}//cout << x << " " << y << " Up " << Up[x][y] << endl;//assert( inmap( nxtpos.first , nxtpos.second ));if(nxtpos.first != x){Data newst = fq;newst.p[idx] = nxtpos;newst.step ++ ;Try_Push( newst );}}// 向下{pair < int , int > nxtpos = mp( pos.first + Down[x][y] , pos.second );rep(j,0,num - 1){if( fq.p[j].second == y && fq.p[j].first <= nxtpos.first && fq.p[j].first > pos.first  ){nxtpos.first = fq.p[j].first - 1;}}//              cout << x << " " << y << " Down " << Down[x][y] << endl;//assert( inmap( nxtpos.first , nxtpos.second ));if(nxtpos.first != x){Data newst = fq;newst.p[idx] = nxtpos;newst.step ++ ;Try_Push( newst );}}// 向左{pair < int , int > nxtpos = mp( pos.first , pos.second - Lft[x][y] );rep(j,0,num - 1){if( fq.p[j].first == x && fq.p[j].second < pos.second && fq.p[j].second >= nxtpos.second  ){nxtpos.second = fq.p[j].second + 1;}}//              cout << x << " " << y << " Lft " << Lft[x][y] << endl;//assert( inmap( nxtpos.first , nxtpos.second ));if(nxtpos.second != y){Data newst = fq;newst.p[idx] = nxtpos;newst.step ++ ;Try_Push( newst );}}// 向右{pair < int , int > nxtpos = mp( pos.first , pos.second + Rht[x][y] );rep(j,0,num - 1){if( fq.p[j].first == x && fq.p[j].second <= nxtpos.second && fq.p[j].second > pos.second  ){nxtpos.second = fq.p[j].second - 1;}}//              cout << x << " " << y << " Rht " << Rht[x][y] << endl;//assert( inmap( nxtpos.first , nxtpos.second ));if(nxtpos.second != y){Data newst = fq;newst.p[idx] = nxtpos;newst.step ++ ;Try_Push( newst );}}}}return -1;
}int main(int argc,char *argv[]){while(~scanf("%d%d%d%d",&num,&M,&N,&Limit)){rep(i,1,N) sf("%s",G[i] + 1);clr(Lft,-1);clr(Up,-1);clr(Down,-1);clr(Rht,-1);rep(i,1,N) rep(j,1,M){GOt_Lft(i,j);Got_Up(i,j);Got_Down(i,j);Got_Rht(i,j);}rep(i,1,N)rep(j,1,M){Up[i][j]--;Down[i][j]--;Lft[i][j]--;Rht[i][j]--;}rep(i,1,N) rep(j,1,M){if(G[i][j]<='4'&&G[i][j]>='1'){int idx = G[i][j] - '1';base[idx] = mp( i , j );}else if(G[i][j]=='X'){targetX = i , targetY = j;}}int ans = bfs();if( ans == -1 ) pf("NO SOLUTION\n");else pf("%d\n",ans);Init();}return 0;
}

轉載于:https://www.cnblogs.com/qscqesze/p/5677522.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/192107.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息