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

UVALive 6888 Ricochet Robots bfs相关推荐

  1. E - Ricochet Robots( dfs+hash优化 )

    E - Ricochet Robots( dfs+hash优化 ) 题目链接:Gym - 100783E 题意: w*h的二维地图中,n个机器人,一个( 或者多个 )特定的点. 每次操作可以指定一个机 ...

  2. UVALive - 2093 Moving Pegs bfs

    题目大意:有一个棋盘,开始时,15个格子上面都有棋子,现在给出n,表示n上面没有棋子,问最少要走几步才能使的最后一个棋子落在n上 解题思路:纪录所有能走的状态,然后bfs,因为要最小的字典序,所以纪录 ...

  3. 弹跳机器人 桌游_《碰撞机器人 Ricochet Robots 》介绍

    其实这游戏也算是老游戏了,只是久违的再介绍一款卧槽的死脑细胞的游戏吧.对于喜欢动脑的人来说非常不错. 游戏人数:2?20人,4,5,6人最佳 游戏评论:这是一款脑力激荡的益智游戏,玩家们要在最短时间内 ...

  4. 复杂系统理论解释了Covid为何粉碎世界

    重点 (Top highlight) Human history is a long saga of people learning to harness ever-increasing amount ...

  5. python 视频下载神器(you-get) 的安装和用法

    0x01 安装 pip3 install you-get $ pip3 install --upgrade you-get 命令行输入you-get 如果有以下回显说明安装成功 0x02 用法 Usa ...

  6. 2016北京区域赛E UVAlive 7672 题目:What a Ridiculous Election 带约束条件的BFS

    这几天做的北京的模拟,当时被这个题给卡住了,自己写的BFS,一直WA,结束后对拍才找到自己的致命错误 自己做的时候直接通过最优情况去推导最有情况,导致自己掉进死胡同了 这里举一个例子,比如变成0103 ...

  7. Robots at Warehouse(搜索+vector的使用)

    Vitaly works at the warehouse. The warehouse can be represented as a grid of n × mcells, each of whi ...

  8. HDU-1459.非常可乐(BFS )

    这道题TLE了很多次,原来一直以为将数字化为最简可以让运算更快,但是去了简化之后才发现,真正耗时的就是化简....还和队友学到了用状态少直接数组模拟刚就能过... 本题大意:给出可乐的体积v1,给出两 ...

  9. DP UVALive 6506 Padovan Sequence

    题目传送门 /*题意:两行数字,相邻列一上一下,或者隔一列两行都可以,从左到右选择数字使和最大DP:状态转移方程:dp[i][j] = max (dp[i][j], dp[1-i][j-1] + a[ ...

最新文章

  1. 一文看懂深度学习模型压缩和加速
  2. Javascript基础知识篇(5): 面向对象之链式调用
  3. php admin配置my sql,安装Mysqlphpadmin
  4. 【Android RTMP】x264 图像数据编码 ( NV21 格式中的 YUV 数据排列 | Y 灰度数据拷贝 | U 色彩值数据拷贝 | V 饱和度数据拷贝 | 图像编码操作 )
  5. 2月1日学习内容整理:算法
  6. 反射学习4-通过反射机制动态创建和访问数组
  7. 注意啦!10 个你需要了解的 Linux 网络和监控命令
  8. leetcode 782. Transform to Chessboard | 782. 变为棋盘(Java)
  9. 解决SWFUpload在Chrome、Firefox浏览器下session找不到的问题
  10. linux驱动编写(设备树)
  11. Nginx + uWSGI + Flask + Vhost
  12. Starling滤镜合集2(新增7种滤镜)
  13. .NET简谈观察者模式
  14. BZOJ2438[中山市选2011] 杀人游戏
  15. 大一高数下册笔记整理_高等数学下册知识点总结.doc
  16. html5在线视频编辑器,WeVideo:视频编辑器
  17. pytorch BCEWithLogitsLoss pos_weight参数解疑
  18. c语言中int和void,关于指针:void(*)void和int(*)int在C中的含义是什么?
  19. 牛牛的宝可梦Go(dp+floyd)
  20. 基于SSM的二手物品交易系统的设计与实现(文末附源码)

热门文章

  1. linux系统 设置网卡ping通主机连上外网
  2. c语言股票最大收益_长期持有指数基金是最好的选择?指数基金的历史年化收益率是多少?...
  3. 把ct图像像素值转化为_2020年大型设备上岗证CT技师真题回顾
  4. tomcat ajp协议安全限制绕过漏洞_Apache tomcat 文件包含漏洞复现(CVE20201938)
  5. 三维计算机视觉(一)--点云处理综述
  6. mysql 下载教程_MySQL下载安装详情图文教程
  7. python伪装浏览器https_Python3 伪装浏览器的方法示例
  8. python装饰器是什么意思_对Python装饰器的理解
  9. zbrush 添加纹理贴图_ZBrush油泥粘土雕塑笔刷Digital Clay Pack
  10. python3 读写json文件,python3没有读取JSON文件righ