BFS -> 僵尸感染 -> 队列
每个点状态的数量 ,每个状态访问一次,想办法将状态转换为int(类似hash)
int visted = [x][y][状态数量];
Queue queue;
void bfs(起点){
if起点符合退出条件,return
起点入队
while(队列不为空){
当前临时点 = queue出队
for(各个方向遍历){
根据当前临时点得到下一个点的位置
if(下一个点的visted没有访问过&&其他条件成立)
下一个点入队
更新下一个的信息(比如到达step)
如果符合退出条件,return
else 继续
}
}
}
}
POJ 1324
#include <cstdio>
#include <iostream>
using namespace std;
#define SIZE 20
#define LENGTH 8
#define SNAKE_STATES 16384 //状态数量,以蛇头为起点,向后的每个点都有4中状态(取整),就提取了特征值
int snake[LENGTH][2];
int stone[SIZE * SIZE][2];
int visited[SIZE + 1][SIZE + 1][SNAKE_STATES];
typedef struct Element{
int x;
int y;
int state;
int step;
} Element;
Element Queue[SIZE * SIZE * SNAKE_STATES];
int head, tail;
int direct[3][3] = {
0, 0, 0,
3, 0, 1,
0, 2, 0,
};
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int getState(int Len){
int state = 0;
for(int i = Len - 1; i > 0; i--){
int x = snake[i][0] - snake[i - 1][0];
int y = snake[i][1] - snake[i - 1][1];
x+=1;
y+=1;
int D = direct[x][y];
state = state * 4 + D;
}
return state;
}
int isStone(int x, int y, int K){
for(int i = 0; i < K; i++){
if(x == stone[i][0] && y == stone[i][1])
return 1;
}
return 0;
}
int isSnake(int x, int y, int state, int L, int nx, int ny){
snake[0][0] = x;
snake[0][1] = y;
for(int i = 1; i < L; i++){
int D = state % 4;
state = state / 4;
snake[i][0] = snake[i - 1][0] + dx[D];
snake[i][1] = snake[i - 1][1] + dy[D];
}
for(int i = 0; i < L; i++){
if(nx == snake[i][0] && ny == snake[i][1]){
return 1;
}
}
return 0;
}
int getMinStep(int M, int N, int L, int K){
Queue[tail].x = snake[0][0];
Queue[tail].y = snake[0][1];
Queue[tail].state = getState(L);
Queue[tail].step = 0;
visited[Queue[tail].x][Queue[tail].y][Queue[tail].state] = 1;
if(Queue[tail].x == 1 && Queue[tail].y == 1) return 0;
tail++;
while(head < tail){
Element curState = Queue[head++];
//cout << "out " << curState.x << " " << curState.y << " " << curState.step << " " << curState.state << endl;
for(int i = 0; i < 4; i++){
int nx = curState.x + dx[i];
int ny = curState.y + dy[i];
int nd;
if(i >= 2) nd = i - 2;
else nd = i + 2;
if(nx >= 1 && nx <= M && ny >= 1 && ny <= N){
int mask = (1 << (2 * L - 2)) - 1;
int nState = ((curState.state * 4) & mask) + nd;
if(!visited[nx][ny][nState] && !isStone(nx, ny, K) && !isSnake(curState.x, curState.y, curState.state, L, nx, ny)){
Queue[tail].x = nx;
Queue[tail].y = ny;
Queue[tail].state = nState;
Queue[tail].step = curState.step + 1;
//cout << "in " << nx << " " << ny << " " << Queue[tail].step << " " << nState << endl;
if(nx == 1 && ny == 1) return Queue[tail].step;
tail++;
visited[nx][ny][nState] = 1;
}
}
}
}
return -1;
}
int main(){
//freopen("input.txt", "r", stdin);
int nC = 1;
while(1){
int M, N, L;
cin >> M >> N >> L;
if(M + N + L == 0) break;
for(int i = 0; i < L; i++){
cin >> snake[i][0] >> snake[i][1];
}
int K;
cin >> K;
for(int i = 0; i < K; i++){
cin >> stone[i][0] >> stone[i][1];
}
head = 0;
tail = 0;
for(int i = 0; i <= M; i++){
for(int j = 0; j <= N; j++){
for(int k = 0; k < SNAKE_STATES; k++){
visited[i][j][k] = 0;
}
}
}
int minStep = getMinStep(M, N, L, K);
cout << "Case " << nC <<": "<< minStep << endl;
nC++;
}
return 0;
}