一.题目链接:

POJ-3322

二.题目大意:

翻砖块:体验

三.分析:

题目不难,把所用东西搞清楚就行了.

这里多写了一个打印路径的,供以后 玩 学习.

四.代码实现:

一.AC 版本

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define lc k * 2
#define rc k * 2 + 1
#define pi acos(-1.0)
#define ll long long
#define ull unsigned long long
using namespace std;

const int M = (int)5e2;
const int mod = 99991;
const int inf = 0x3f3f3f3f;

int n, m;
char s[M + 5][M + 5];

struct node
{
    int x, y, lie;
}st, ed, p, t;
queue <node> q;
///右左下上
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int step[M + 5][M + 5][3];

int next_x[3][4] =
{
    {0, 0, 1, -2},
    {0, 0, 1, -1},
    {0, 0, 2, -1}
};

int next_y[3][4] =
{
    {1, -2, 0, 0},
    {2, -1, 0, 0},
    {1, -1, 0, 0}
};

int next_lie[3][4] =
{
    {1, 1, 2, 2},
    {0, 0, 1, 1},
    {2, 2, 0, 0}
};

bool valid(int x, int y)
{
    return x >= 1 && x <= n && y >= 1 && y <= m;
}

void parse_st_ed()
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            if(s[i][j] == 'O')
                ed.x = i, ed.y = j, ed.lie = 0, s[i][j] = '.';
            else if(s[i][j] == 'X')
            {
                st.x = i, st.y = j, st.lie = 0, s[i][j] = '.';
                for(int k = 0; k < 4; k += 2)
                {
                    int x = i + dx[k], y = j + dy[k];
                    if(valid(x, y) && s[x][y] == 'X')
                    {
                        st.lie = k / 2 + 1;
                        s[x][y] = '.';
                        break;
                    }
                }
            }
        }
    }
}

bool valid(struct node t)
{
    if(!valid(t.x, t.y))                                                  return 0;
    if(~step[t.x][t.y][t.lie])                                            return 0;
    if(s[t.x][t.y] == '#')                                                return 0;
    if(t.lie == 0 && s[t.x][t.y] != '.')                                  return 0;
    if(t.lie == 1 && (!valid(t.x, t.y + 1) || s[t.x][t.y + 1] == '#'))    return 0;
    if(t.lie == 2 && (!valid(t.x + 1, t.y) || s[t.x + 1][t.y] == '#'))    return 0;
    return 1;
}

int bfs()
{
    memset(step, -1, sizeof(step));
    step[st.x][st.y][st.lie] = 0;
    while(!q.empty())   q.pop();
    q.push(st);
    while(!q.empty())
    {
        p = q.front();
        q.pop();
        for(int i = 0; i < 4; ++i)
        {
            t = p;
            t.x += next_x[t.lie][i];
            t.y += next_y[t.lie][i];
            t.lie = next_lie[t.lie][i];
            if(valid(t))
            {
                step[t.x][t.y][t.lie] = step[p.x][p.y][p.lie] + 1;
                if(t.x == ed.x && t.y == ed.y && t.lie == ed.lie)
                    return step[t.x][t.y][t.lie];
                q.push(t);
            }
        }
    }
    return -1;
}

int main()
{
    while(~scanf("%d %d", &n, &m) && (n + m))
    {
        for(int i = 1; i <= n; ++i)
            scanf("%s", s[i] + 1);
        parse_st_ed();
        int ans = bfs();
        if(~ans)
            printf("%d\n", ans);
        else
            printf("Impossible\n");
    }
    return 0;
}

二.打印路径版本

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define lc k * 2
#define rc k * 2 + 1
#define pi acos(-1.0)
#define ll long long
#define ull unsigned long long
using namespace std;

const int M = (int)5e2;
const int mod = 99991;
const int inf = 0x3f3f3f3f;

int n, m;
char s[M + 5][M + 5];

struct node
{
    int x, y, lie;
} st, ed, p, t, fa[M + 5][M + 5][3];
queue <node> q;
///右左下上
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int step[M + 5][M + 5][3];

int next_x[3][4] =
{
    {0, 0, 1, -2},
    {0, 0, 1, -1},
    {0, 0, 2, -1}
};

int next_y[3][4] =
{
    {1, -2, 0, 0},
    {2, -1, 0, 0},
    {1, -1, 0, 0}
};

int next_lie[3][4] =
{
    {1, 1, 2, 2},
    {0, 0, 1, 1},
    {2, 2, 0, 0}
};

bool valid(int x, int y)
{
    return x >= 1 && x <= n && y >= 1 && y <= m;
}

void parse_st_ed()
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            if(s[i][j] == 'O')
                ed.x = i, ed.y = j, ed.lie = 0, s[i][j] = '.';
            else if(s[i][j] == 'X')
            {
                st.x = i, st.y = j, st.lie = 0, s[i][j] = '.';
                for(int k = 0; k < 4; k += 2)
                {
                    int x = i + dx[k], y = j + dy[k];
                    if(valid(x, y) && s[x][y] == 'X')
                    {
                        st.lie = k / 2 + 1;
                        s[x][y] = '.';
                        break;
                    }
                }
            }
        }
    }
}

bool valid(struct node t)
{
    if(!valid(t.x, t.y))
        return 0;
    if(~step[t.x][t.y][t.lie])
        return 0;
    if(s[t.x][t.y] == '#')
        return 0;
    if(t.lie == 0 && s[t.x][t.y] != '.')
        return 0;
    if(t.lie == 1 && (!valid(t.x, t.y + 1) || s[t.x][t.y + 1] == '#'))
        return 0;
    if(t.lie == 2 && (!valid(t.x + 1, t.y) || s[t.x + 1][t.y] == '#'))
        return 0;
    return 1;
}

int bfs()
{
    memset(step, -1, sizeof(step));
    step[st.x][st.y][st.lie] = 0;
    while(!q.empty())
        q.pop();
    q.push(st);
    while(!q.empty())
    {
        p = q.front();
        q.pop();
        for(int i = 0; i < 4; ++i)
        {
            t = p;
            t.x += next_x[t.lie][i];
            t.y += next_y[t.lie][i];
            t.lie = next_lie[t.lie][i];
            if(valid(t))
            {
                step[t.x][t.y][t.lie] = step[p.x][p.y][p.lie] + 1;
                fa[t.x][t.y][t.lie] = p;
                if(t.x == ed.x && t.y == ed.y && t.lie == ed.lie)
                    return step[t.x][t.y][t.lie];
                q.push(t);
            }
        }
    }
    return -1;
}

/**
9 14
###EEEEEEE####
###EEEEEEE####
....#####...##
...#######..##
...#######..##
.X.##....EEEEE
...##....EEEEE
#####.O.##EE.E
#####...##EEEE
0 0
**/

void print_solution()
{
    stack <node> Stack;
    p = ed;
    Stack.push(p);
    while(p.x != st.x || p.y != st.y || p.lie != st.lie)
    {
        p = fa[p.x][p.y][p.lie];
        Stack.push(p);
    }
    p = Stack.top(), Stack.pop();
    getchar();
    for(int step = 1; !Stack.empty(); ++step)
    {
        printf("%2d.", step);
        t = Stack.top(), Stack.pop();
        for(int i = 0; i < 4; ++i)
        {
            if(p.x + next_x[p.lie][i] == t.x && p.y + next_y[p.lie][i] == t.y && next_lie[p.lie][i] == t.lie)
            {
                switch(i)
                {
                    case 0: printf("右");break;
                    case 1: printf("左");break;
                    case 2: printf("下");break;
                    case 3: printf("上");break;
                }
                break;
            }
        }
        printf(":(%d,%d,%d)->(%d,%d,%d)\n", p.x, p.y, p.lie, t.x, t.y, t.lie);
        p = t;
        if(step % 5 == 0)   getchar();
    }
}

int main()
{
    while(~scanf("%d %d", &n, &m) && (n + m))
    {
        for(int i = 1; i <= n; ++i)
            scanf("%s", s[i] + 1);
        parse_st_ed();
        int ans = bfs();
        if(~ans)
        {
            printf("%d\n", ans);
            print_solution();
        }
        else
            printf("Impossible\n");
    }
    return 0;
}