题目大意:两张图,都是6*6,同时操纵两张图上的球(它们的运动都是相同的,如果其中有一个被挡住那么那个求就不会动),题目下面有一张表,会告诉你地图上的数字变为二进制之后每一位的意义;
分析:非常蛋疼的BFS,没有什么技术含量,就是写起来非常麻烦非常消耗时间,这题目是我们在准备牡丹江regional时组队合练出的题目,当时我们错误的估计了这题目的难度没敲。。。感觉如果早点写这题的话应该可以4题的,以下是AC代码:
/*Problem : 3713 ( Double Maze ) Judge Status : Accepted
RunId : 11825237 Language : C++ Author : Burglar
Code Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta*/
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <queue>
#define MAXN 10005
#define N 8
using namespace std;
int map_first[N][N];
int map_second[N][N];
int judge[N][N][N][N];//标记状态
int move_step[4][2] = {{1, 0}, {0, -1}, {0, 1}, {-1, 0}};//保证字典序最小
struct Node
{
int x1, x2, y1, y2;//两张图上面的球的坐标
int dir;//方向
int qian;//记录前驱,用于递归输出;
}Q[MAXN];//队列的长度其实最多也就6 * 6 * 6 * 6
struct Point
{
int x, y;
};
Point first_star, second_star, first_end, second_end;
char Dir(int i)
{
if(i == 0) return 'D';
else if(i == 1) return 'L';
else if(i == 2) return 'R';
else
return 'U';
}
void print(int i)//递归输出
{
if(i == -1) printf("-1");
if(i > 0) print(Q[i].qian);
if(i > 0) printf("%c",Dir(Q[i].dir));
}
void input()//输入第二张图
{
for(int i = 1; i <= 6; i++)
{
for(int j = 1; j <= 6; j++)
{
scanf("%d",&map_second[i][j]);
if( (map_second[i][j] >> 5) & 1 )
{
second_star.x = i;
second_star.y = j;
}
if( (map_second[i][j] >> 6) & 1 )
{
second_end.x = i;
second_end.y = j;
}
}
}
}
void copy_map()//把第二张图拷贝给第一张图
{
for(int i = 1; i <= 6; i++)
{
for(int j = 1; j <= 6; j++)
{
map_first[i][j] = map_second[i][j];
}
}
first_star = second_star;
first_end = second_end;
}
bool in_map(int x, int y)//判断点在不在图里面
{
if(1 <= x && x <= 6 && 1 <= y && y <= 6) return true;
return false;
}
bool first_not_hole(int x, int y)//判断某个点是不是洞
{
if( (map_first[x][y] >> 4) & 1) return true;
return false;
}
bool second_not_hole(int x, int y)
{
if( (map_second[x][y] >> 4) & 1) return true;
return false;
}
bool first_canmove(int x, int y, int dir)//对于某个点可不可以往dir方向移动
{
if( ((map_first[x][y] >> 0) & 1 ) && dir == 1) return false;
if( ((map_first[x][y] >> 1) & 1 ) && dir == 0) return false;
if( ((map_first[x][y] >> 2) & 1 ) && dir == 2) return false;
if( ((map_first[x][y] >> 3) & 1 ) && dir == 3) return false;
return true;
}
bool second_canmove(int x, int y, int dir)
{
if( ((map_second[x][y] >> 0) & 1 ) && dir == 1) return false;
if( ((map_second[x][y] >> 1) & 1 ) && dir == 0) return false;
if( ((map_second[x][y] >> 2) & 1 ) && dir == 2) return false;
if( ((map_second[x][y] >> 3) & 1 ) && dir == 3) return false;
return true;
}
int BFS()//广搜
{
int now, len;
memset(judge, 0, sizeof(judge));
memset(Q, 0, sizeof(Q));
Node last, next;
next.x1 = first_star.x;
next.y1 = first_star.y;
next.x2 = second_star.x;
next.y2 = second_star.y;
next.dir = -1;
next.qian = -1;
judge[next.x1][next.y1][next.x2][next.y2] = 1;
now = 0, len = 1;
Q[now] = next;
while(now < len)
{
last = Q[now];
now++;
if( ( (map_first[last.x1][last.y1] >> 6) & 1 )&& ( (map_second[last.x2][last.y2] >> 6) & 1 ) )//判断是否到终点
{
return (now - 1);
break;
}
for(int i = 0; i < 4; i++)
{
next = last;
if(first_canmove(last.x1, last.y1, i))
{
next.x1 = last.x1 + move_step[i][0];
next.y1 = last.y1 + move_step[i][1];
if(!first_not_hole(next.x1, next.y1) || !in_map(next.x1, next.y1)) continue;
}
if(second_canmove(last.x2, last.y2, i))
{
next.x2 = last.x2 + move_step[i][0];
next.y2 = last.y2 + move_step[i][1];
if(!second_not_hole(next.x2, next.y2) || !in_map(next.x2, next.y2)) continue;
}
if(!judge[next.x1][next.y1][next.x2][next.y2])
{
judge[next.x1][next.y1][next.x2][next.y2] = 1;
next.dir = i;
next.qian = now - 1;
Q[len] = next;
len++;
}
}
}
return -1;
}
int main()
{
int ans, case_num;
scanf("%d",&case_num);
for(int i = 1; i <= 6; i++)
{
for(int j = 1; j <= 6; j++)
{
scanf("%d",&map_first[i][j]);
if( (map_first[i][j] >> 5) & 1)
{
first_star.x = i;
first_star.y = j;
}
if( (map_first[i][j] >> 6) & 1)
{
first_end.x = i;
first_end.y = j;
}
}
}
case_num--;
while(case_num--)
{
input();
print(BFS());
printf("\n");
copy_map();
}
return 0;
}
各位大神们看完就不要纠结我的函数命名了。。比较丑 我的代码风格还在成型中。。。