新题目大意:

  三个棋子按照先后顺序,可以随意方向合法地走到空位置上(而不是像原题light oj-1055中的一样三个棋子每次走的方向都一致),当三个棋子全部走进目标地点,就结束;求需要指挥的最少次数。

思路:

  BFS

  在每次进行指挥时,需要分别指挥三个棋子,每个棋子至多有五种走法(第五种为原地不动——因为前进时受阻没法动的时候),同时枚举三个棋子的当前位置进入队列中。由于每个棋子在走的时候会影响到后续的点的移动,故需要三重for循环来枚举每次三个点的移动先后顺序,然后依旧三重循环来枚举搞定三个点的移动方向,然后判断-标记-加入队列?结束。

标记去重的BFS思路:
  三个棋子共同组成的局面可以不分先后相互等价;用vis[A.x][A.y][B.x][B.y][C.x][C.y]来进行标记!
  所以对于每一个局面,都有其余5个分先后的局面与其等价。即ABC=ACB=BAC=BCA=CAB=CBA.
/* 
4
..A.
XXXB
..C.
....
/*或许可以再加一个优先队列优化一下时间:排序标准是三个点与三个终点的最小距离之和;或许还可以再加一个剪枝的方法:每次搜索一个点时需要枚举四个方位,可以事先统计所有空点周围不是的‘#’的方向数量,当每个点可以作出的选择数等于上述点数就continue。*/
//下面 极大值测试3.9s(Tmax==50),
1
9
AB....C..
.........
.........
.........
.........
.........
.........
.........
X..X..X..
 
*/
 
胡搞的代码:
#define 其余头文件...
#define N 10
#define inf 0x3f3f3f3f
char mp[N][N];
int n;
struct node{
int x,y;
}just;
struct group{//一个局面三个点的位置,位置之间等价
node p[];//0,1,2三位有效存储
int step;
}st;
int dir[][]={{,},{,},{,},{,-},{-,} };
bool vis[N][N][N][N][N][N];//标记数组,模拟每一组棋子组合成的局面
bool judge_end(group x){ //判断当前局面是否达到结束要求
int num=;
for(int i=;i<;i++){
if(mp[x.p[i].x][x.p[i].y]=='X')
num++;
}
if(num==)return true;
return false;
}
void getvis(group a){//从一个局面获取6个标记
vis[a.p[].x][a.p[].y][a.p[].x][a.p[].y][a.p[].x][a.p[].y]=true;
vis[a.p[].x][a.p[].y][a.p[].x][a.p[].y][a.p[].x][a.p[].y]=true;
vis[a.p[].x][a.p[].y][a.p[].x][a.p[].y][a.p[].x][a.p[].y]=true;
vis[a.p[].x][a.p[].y][a.p[].x][a.p[].y][a.p[].x][a.p[].y]=true;
vis[a.p[].x][a.p[].y][a.p[].x][a.p[].y][a.p[].x][a.p[].y]=true;
vis[a.p[].x][a.p[].y][a.p[].x][a.p[].y][a.p[].x][a.p[].y]=true;
}
bool getstep(int i,int k,group a){//i表示第i个点的下一步操作,向dir[k]进行下一步
node s=a.p[i];
s.x=s.x+dir[k][];
s.y=s.y+dir[k][];
if(s.x>=n||s.y>=n||s.x<||s.y<)return false;//越界,‘#’,走到同一局面其他点上, false
if(mp[s.x][s.y]=='#')return false;
for(int j=;j<=;j++){
if(i!=j&&(a.p[j].x==s.x)&&(a.p[j].y==s.y))
return false;
}
just=s;//存储的全局变量
return true;
}
void debug(group a){
printf("*%dstep* *A*(%d,%d) ",a.step,a.p[].x,a.p[].y);
printf("*B*(%d,%d) ",a.p[].x,a.p[].y);
printf("*C*(%d,%d)\n",a.p[].x,a.p[].y);
}
int bfs(){
memset(vis,false,sizeof(vis));
group now,ne,ne2,ne3;
queue<group>Q;
st.step=;
Q.push(st); //标记起点局面
getvis(st);
while(Q.size()){
now=Q.front();
Q.pop();
if(judge_end(now))return now.step;
//按ABC,ACB,BAC,BCA,CAB,CBA六种先后方式来枚举,i-j-k三重循环
for(int i=;i<;i++){//枚举第一个先走的编号
for(int j=;j<;j++){//枚举第二个编号
for(int k=;k<;k++){//第三个
if(j==i||i==k||j==k)continue; for(int x=;x<;x++){ //x-y-z三种循环分别表示i-j-k的走位方向
ne=now;
if(getstep(i,x,ne)==false)continue;
else ne.p[i]=just;
for(int y=;y<;y++){
ne2=ne;
if(getstep(j,y,ne2)==false)continue;
else ne2.p[j]=just;
for(int z=;z<;z++){
ne3=ne2;
if(getstep(k,z,ne3)==false)continue;
else ne3.p[k]=just;
//在这里得到了合格的next3局面,然后进行判断
if(vis[ne3.p[].x][ne3.p[].y][ne3.p[].x][ne3.p[].y][ne3.p[].x][ne3.p[].y]==true)
continue;//重复走过了
ne3.step=now.step+;
// debug(ne3);
getvis(ne3);//进行标记
if(judge_end(ne3)){
// printf("--up|------now :");debug(now);
return ne3.step;
}
else
Q.push(ne3);
}
}
}
}
}
}
}
return -;
}
int main()
{
int T,cas=;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=;i<n;i++)//读图
scanf("%s",mp[i]);
int num1=;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
if(mp[i][j]>='A'&&mp[i][j]<='C')
st.p[num1].x=i,st.p[num1++].y=j;
}
}
printf("Case %d: ",++cas);
int ans=bfs();
if(ans!=-)
printf("%d\n",ans);
else
printf("trapped\n");
} return ;
}

上一篇:【loj-1055-Going Together-三个棋子推箱子走到目的地--讲预判的bfs】

最新文章

  1. 读取properties配置文件的方法
  2. 高效 Java Web 开发框架 JessMA v3.3.1 正式发布
  3. [转]响应式表格jQuery插件 – Responsive tables
  4. NAND驱动
  5. Linux下mysql的安装和使用(C语言)
  6. Django基本介绍
  7. CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate)(转载)
  8. 利用谷歌开源工具cAdvisor 结合influxdb存储+Grafana前端展示进行Docker容器的监控
  9. 前端-javascript-ECMAScript5.0
  10. Oracle零碎总结:结构-工具-创建语句
  11. GNU Radio GRC HackRF实现FM接收
  12. Visual Studio使用中的问题
  13. java set初始化问题
  14. Redis学习总结之一——Redis初入
  15. SQLmap源码分析之框架初始化(一)
  16. Go语言入门(二)Go语言中的变量、常量、数据类型、流程控制以及函数
  17. (转)centos6.5下Zabbix系列之Zabbix安装搭建及汉化
  18. Android应用经典主界面框架之中的一个:仿QQ (使用Fragment, 附源代码)
  19. Spark常用算子-KeyValue数据类型的算子
  20. hadoop中节点上的nodemanager一直启动不起来

热门文章

  1. WXS --注释
  2. springboot 通过docker 打包编译镜像
  3. qt qml 类型之Keys
  4. CentOS7.6安装Pycharm并添加快捷方式
  5. [转帖]时序数据库技术体系 – InfluxDB TSM存储引擎之数据读取
  6. Python基础系列讲解——try_except异常处理机制
  7. C/C++中内存泄漏、内存溢出与野指针的解释与说明
  8. xorm表结构操作实例
  9. (转)基于FFPMEG2.0版本的ffplay代码分析
  10. gulp做的前端代码压缩报错,揭示具体错误 信息