码迷,mamicode.com
首页 > 其他好文 > 详细

sicily 1215 脱离地牢

时间:2014-12-27 11:26:14      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:sicily   算法与数据结构   algorithm   c++   

做Sicily 1215脱离地牢 这一题,一直Restrict function,都快崩溃了。

最后发现是内存泄露,就是new出来的东西没有及时delete导致的。

具体是在广度优先搜索的时候,每找一次邻居就new出一些节点,有些节点已被visited了然后我直接忽略它们,实际上是得把它们delete掉的,还有就是pop出一个节点后,在处理完邻居之后要把这个节点delete了

贴个代码片段:
技术分享
第32,35行便是要注意的地方。
运行效率:0秒,312KB
完整代码如下:
// Problem#: 1215
// Submission#: 2642938
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include<iostream>
#include<stdio.h>
#include<queue> 
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
char **prison;
bool *visited;
unsigned char *dotPerLine = NULL;
unsigned char **oneLineDot = NULL;
int n, m;
char dirParis[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
char dirHelen[4][2];
int dotCount;
struct Node
{
    int px;
    int py;
    int hx;
    int hy;
    int step;
    Node()
    {
        step = 0;
        parent = NULL;
    }
    Node* parent;
};
int hashPoint(int x, int y)
{
    int p=0;
        
    p+=dotPerLine[x-1];

//  for(int j = 0; j < y; j++)
//  {
//      if(prison[x][j] == '.' || prison[x][j] == 'H' || prison[x][j] == 'P')
//          p++;
//  }
//  
    p+=oneLineDot[x][y-1];

    return p;
}
int hashNode(Node* node)
{   
    return hashPoint(node->hx-1,node->hy-1)*dotCount+hashPoint(node->px-1,node->py-1); 
}
//bool cmp(const Node* a, const Node* b)
//{
//  int disA = abs(a->px-a->hx) +abs(a->py-a->hy);
//  int disB = abs(b->px-b->hx) +abs(b->py-b->hy);
//  return disA < disB;
//}
vector<Node*> getAdj(Node* node)
{
    vector<Node*> ret;  
    for(int i = 0; i < 4; i++)
    {
        char pNext = prison[node->px-1+dirParis[i][0]][node->py-1+dirParis[i][1]];
        char hNext = prison[node->hx-1+dirHelen[i][0]][node->hy-1+dirHelen[i][1]];
        if(pNext != '#' && pNext != '!')
        {
            if(hNext != '!')
            {
                Node* newNode = new Node;               
                newNode->px = node->px+dirParis[i][0];
                newNode->py = node->py+dirParis[i][1];              
                if(hNext == '#')
                {
                    newNode->hx = node->hx;
                    newNode->hy = node->hy;
                }
                else
                {
                    newNode->hx = node->hx+dirHelen[i][0];
                    newNode->hy = node->hy+dirHelen[i][1];
                }
                newNode->step = node->step+1;
                ret.push_back(newNode);
                newNode->parent = node;
            }
        }
    }
    return ret;
}
bool isPass(Node* node)
{
    return node->px == node->hx && node->py == node->hy 
    || node->px == node->parent->hx && node->py == node->parent->hy
    && node->hx == node->parent->px && node->hy == node->parent->py;
}
int bfs(Node* node)
{   
    queue<Node*> Q;
    Q.push(node);
    while(!Q.empty())
    {
        Node* node = Q.front();
        Q.pop();
        vector<Node*> adj = getAdj(node);   
        //sort(adj.begin(),adj.end(),cmp);
        for(int i = 0; i < adj.size(); i++)
        {
            Node* child = adj.at(i);
            if(child->step > 255)
                return -1;
            int index = hashNode(child);
            if(!visited[index])
            {
                visited[index] = true;
                if(!isPass(child))  
                {                   
                    Q.push(child);
                }
                else
                {                   
                    return child->step;
                }
            }       
            else
            {
                delete child;
            }   
        }
        delete node;
    }
    return -1;
}
int main()
{
    while(cin >> n >> m)
    {
        dotPerLine = new unsigned char[n];
        memset(dotPerLine,0,n); 
        oneLineDot = new unsigned char*[n];     
        prison = new char*[n];      
        for(int i = 0; i < n; i++)
        {                   
            prison[i] = new char[m];    
            cin >> prison[i];
        }                   
        for(int i = 0; i < n; i++)
        {
            oneLineDot[i] = new unsigned char[m];   
            memset(oneLineDot[i],0,m);          
        }
        char d[4];
        cin >> d;
        for(int i = 0; i < 4; i++)
        {
            switch(d[i])
            {
            case'N':
                dirHelen[i][0] = -1;
                dirHelen[i][1] = 0;
                break;
            case'S':
                dirHelen[i][0] = 1;
                dirHelen[i][1] = 0;
                break;
            case'W':
                dirHelen[i][0] = 0;
                dirHelen[i][1] = -1;
                break;
            case'E':
                dirHelen[i][0] = 0;
                dirHelen[i][1] = 1;
                break;                                          
            }
        } 
        //find initial position
        Node* init = new Node;      
        dotCount = 0;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
            {
                if(prison[i][j] == '.')
                {
                    oneLineDot[i][j] = 1;
                    dotCount++;
                    dotPerLine[i]++;
                }
                else if(prison[i][j] == 'H')
                {
                    init->hx = i+1;
                    init->hy = j+1;
                    oneLineDot[i][j] = 1;
                    dotCount++;
                    dotPerLine[i]++;
                }
                else if(prison[i][j] == 'P')
                {
                    init->px = i+1;
                    init->py = j+1;
                    oneLineDot[i][j] = 1;
                    dotCount++;
                    dotPerLine[i]++;
                }                               
            }   
        for(int i = 1; i < n-1; i++)
        {
            dotPerLine[i] += dotPerLine[i-1];           
            for(int j = 2; j < m-1; j++)
            {
                oneLineDot[i][j] += oneLineDot[i][j-1];                     
            }           
        }           
        int count = dotCount*dotCount;
        visited = new bool[count];
        memset(visited,0,count);    
        visited[hashNode(init)] = true;
        int result = bfs(init);
        if(result == -1)
            cout << "Impossible" << endl;
        else        
            cout << result << endl;     
        for(int i = 0; i < n; i++)
        {
            delete [] prison[i];            
            delete [] oneLineDot[i];
        }       
        delete [] prison;
        delete [] dotPerLine;
        delete [] oneLineDot;
        delete [] visited;
    }
}                                 


sicily 1215 脱离地牢

标签:sicily   算法与数据结构   algorithm   c++   

原文地址:http://blog.csdn.net/chz429/article/details/42191227

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!