POJ 1024--Tester Program

题意

题目的大概意思是讲有一个迷宫游戏,给出其布局,和一个最佳行走路线,要求判断这个最佳路线是否是唯一的最短路线。同时,如果有多余(不影响结果)的墙也不行。

分析

我们来考虑每一面墙的作用,假如这面墙是必要的(拆了影响结果)。那么从这面墙到起点的距离加上到终点的距离必然小于给出的最佳路线长度。

所以,可以分别从起点和终点出发,假定给出的最佳路线长度为n,那么从起点和终点分别走n步(广度搜索),得到距离起点和终点n步的范围。然后再计算一下每一面墙分别到起点和终点的距离之和,如果一面墙的任意一面不在n步范围之内,显然这面墙是没有必要的。当然,如果距离之和大于最佳路线,也是没有必要的。

至于是不是唯一路线,从起点到终点广度搜索一遍即可确定。

代码如下:
Memory: 252K Time: 16MS Length: 178LINES

#include<iostream>
#include<string>
using namespace std;
struct PointPair { int x1, y1, x2, y2; };
struct PointandPath 
{ 
    int x, y; 
    string curpath; 
    PointandPath* next;  
    PointandPath(int a, int b, string s) 
    { x = a; y = b; curpath = s; next = NULL; }
};
struct DirectionSet { bool up, right, down, left; };
int width, height;
string path;
int walls;
int* stepmatrix;
int* stepmatrix2;
DirectionSet* map_direction;
int endx = 0, endy = 0;
PointPair* wallcoor;
string bestpath;
bool* visit;
void BuildMap()
{
    for (int i = 0; i < width; ++i) 
        map_direction[i * height].down = map_direction[i * height + height - 1].up = false;
    for (int i = 0; i < height; ++i)    
        map_direction[i].left = map_direction[(width - 1) * height + i].right = false;
    int count = 0;
    while (count < walls)
    {
        if (wallcoor[count].x1 < wallcoor[count].x2)    
            map_direction[wallcoor[count].x1 * height + wallcoor[count].y1].right = map_direction[wallcoor[count].x2 * height + wallcoor[count].y2].left = false;
        else if (wallcoor[count].x2 < wallcoor[count].x1) 
            map_direction[wallcoor[count].x2 * height + wallcoor[count].y2].right = map_direction[wallcoor[count].x1 * height + wallcoor[count].y1].left = false;
        else if (wallcoor[count].y1 < wallcoor[count].y2) 
            map_direction[wallcoor[count].x1 * height + wallcoor[count].y1].up = map_direction[wallcoor[count].x2 * height + wallcoor[count].y2].down = false;
        else if (wallcoor[count].y2 < wallcoor[count].y1) 
            map_direction[wallcoor[count].x1 * height + wallcoor[count].y1].down = map_direction[wallcoor[count].x2 * height + wallcoor[count].y2].up = false;
        ++count;
    }
}
void Traverse(int x, int y, const int dx, const int dy, int& count, int* matrix)
{
    memset(visit, true, sizeof(bool) * width * height);
    PointandPath* head = new PointandPath(x, y, "");
    PointandPath* rear = head;
    visit[x * height + y] = false;
    while (head)
    {
        if (head->x == dx && head->y == dy)
        {
            if (bestpath.length() == 0 || bestpath.length() > head->curpath.length())
            {
                bestpath = head->curpath;
                count = 1;
            }
            else if (head->curpath.length() == bestpath.length() && head->curpath != bestpath)      
                ++count;
        }
        matrix[head->x * height + head->y] = head->curpath.length();
        if (map_direction[head->x * height + head->y].right && visit[(head->x + 1) * height + head->y] && 
            (head->curpath.length() + 1 <= matrix[(head->x + 1) * height + head->y] ||  matrix[(head->x + 1) * height + head->y] == 0) && 
            head->curpath.length() + 1 <= path.length())
        {
            rear = rear->next = new PointandPath(head->x + 1, head->y, head->curpath + 'R');    
            visit[(head->x + 1) * height + head->y] = false;
        }
        if (map_direction[head->x * height + head->y].left && visit[(head->x - 1) * height + head->y] && 
            (head->curpath.length() + 1 <= matrix[(head->x - 1) * height + head->y] || matrix[(head->x - 1) * height + head->y] == 0) && 
            head->curpath.length() + 1 <= path.length())
        {
            rear = rear->next = new PointandPath(head->x - 1, head->y, head->curpath + 'L'); 
            visit[(head->x - 1) * height + head->y] = false;
        }
        if (map_direction[head->x * height + head->y].up && visit[head->x * height + head->y + 1] && 
            (head->curpath.length() + 1 <= matrix[head->x * height + head->y + 1] || matrix[head->x * height + head->y + 1] == 0) &&
            head->curpath.length() + 1 <= path.length())
        {
            rear = rear->next = new PointandPath(head->x, head->y + 1, head->curpath + 'U'); 
            visit[head->x * height + head->y + 1] = false;
        }
        if (map_direction[head->x * height + head->y].down && visit[head->x * height + head->y - 1] && 
            (head->curpath.length() + 1 <= matrix[head->x * height + head->y - 1] || matrix[head->x * height + head->y - 1] == 0) && 
            head->curpath.length() + 1 <= path.length())
        {
            rear = rear->next = new PointandPath(head->x, head->y - 1, head->curpath + 'D');    
            visit[head->x * height + head->y - 1] = false;
        }
        PointandPath* p = head;
        head = head->next;
        delete p;
    }
}
inline bool AtStartorEnd(int x, int y)
{
    if ((x == 0 && y == 0) || (x == endx && y == endy))
        return true;
    else
        return false;
}
int shorter(int pos)
{
    int tmp1 = 0, tmp2 = 0;
    if ((stepmatrix[wallcoor[pos].x1 * height + wallcoor[pos].y1] != 0 || AtStartorEnd(wallcoor[pos].x1, wallcoor[pos].y1)) && 
        (stepmatrix2[wallcoor[pos].x2 * height + wallcoor[pos].y2] != 0 || AtStartorEnd(wallcoor[pos].x2, wallcoor[pos].y2)))
        tmp1 = stepmatrix[wallcoor[pos].x1 * height + wallcoor[pos].y1] + stepmatrix2[wallcoor[pos].x2 * height + wallcoor[pos].y2];
    if ((stepmatrix[wallcoor[pos].x2 * height + wallcoor[pos].y2] != 0 || AtStartorEnd(wallcoor[pos].x2, wallcoor[pos].y2)) && 
        (stepmatrix2[wallcoor[pos].x1 * height + wallcoor[pos].y1] != 0 || AtStartorEnd(wallcoor[pos].x1, wallcoor[pos].y1)))
        tmp2 = stepmatrix[wallcoor[pos].x2 * height + wallcoor[pos].y2] + stepmatrix2[wallcoor[pos].x1 * height + wallcoor[pos].y1];
    if (tmp1 == 0)      return tmp2 == 0 ? 0 : tmp2 + 1;
    if (tmp2 == 0)  return tmp1 == 0 ? 0 : tmp1 + 1;
    else        return tmp1 < tmp2 ? tmp1 + 1 : tmp2 + 1;
}
int main()
{
    int cases;
    cin >> cases;
    while (cases-- > 0)
    {
        cin >> width >> height >> path >> walls;
        endx = 0;
        endy = 0;
        wallcoor = new PointPair[walls];
        stepmatrix = new int[height * width];
        stepmatrix2 = new int[height * width];
        visit = new bool[height * width];
        map_direction = new DirectionSet[height * width];
        memset(stepmatrix, 0, sizeof(int) * height * width);
        memset(stepmatrix2, 0, sizeof(int) * height * width);
        memset(wallcoor, 0, sizeof(PointPair) * walls);
        memset(map_direction, true, sizeof(DirectionSet) * height * width);
        for (int i = 0; i < walls; ++i)
            cin >> wallcoor[i].x1 >> wallcoor[i].y1 >> wallcoor[i].x2 >> wallcoor[i].y2;
        BuildMap();
        int key = 0;
        stepmatrix2[0] = path.length();
        while (key < path.length())
        {
            if (path[key] == 'R') { if (map_direction[endx * height + endy].right) ++endx;  else break; }
            else if (path[key] == 'U') { if (map_direction[endx * height + endy].up) ++endy; else break; }
            else if (path[key] == 'L') { if (map_direction[endx * height + endy].left) --endx;  else break; }
            else if (path[key] == 'D') { if (map_direction[endx * height + endy].down) --endy;  else break; }
            stepmatrix[endx * height + endy] = ++key;
            stepmatrix2[endx * height + endy] = path.length() - key;
        }
        if (key == path.length())
        {
            int count = 0;
            bestpath = "";
            Traverse(0, 0, endx, endy, count, stepmatrix);
            if (count == 1 && bestpath == path)
            {
                Traverse(endx, endy, 0, 0, count, stepmatrix2);
                int i = 0;
                while (i < walls)
                {
                    int length = shorter(i++);
                    if (length > path.length() || length == 0)
                    {
                        cout << "INCORRECT" << endl;
                        break;
                    }
                }
                if (i == walls)     cout << "CORRECT" << endl;
            }
            else        cout << "INCORRECT" << endl;
        }
        else    cout << "INCORRECT" << endl;
        delete[] wallcoor;
        delete[] stepmatrix;
        delete[] stepmatrix2;
        delete[] map_direction;
        delete[] visit;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值