蓝桥杯算法提高 -- 学霸的迷宫

思路 : A* 寻路配合优先队列

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdio>
#include <queue>
using namespace std; 

const int MAXINT = 0x70FFFFF;

// 格子类
class Cell
{
public:
	static int DestRow,DestCol;
public:
	bool IsVisited;
	bool IsOpened;
	int NowStep;
	Cell* prevSite;
	int op;
private:
	int Row,Col;	
	int EstimateValue;
public:
	Cell():NowStep(MAXINT),prevSite(NULL){
		op = Row = Col = -1;
		IsOpened = IsVisited = false;
	}
	void SetCoordinate( int row, int col ){
		Row = row++;
		Col = col++;
		EstimateValue = abs( Cell::DestRow - row ) + abs( Cell::DestCol - col);
	}
	int GetEstimate()const{
		return EstimateValue;
	}
	int RowIndex()const{return Row;}
	int ColIndex()const{return Col;}
}; 

struct CellCompare
{
public:
	
	bool operator()( const Cell* b, const Cell* a )
	{
		if( a->NowStep < b->NowStep ) return true;
		else if( a->NowStep == b->NowStep ) {
			if( a->GetEstimate() < b->GetEstimate() ) return true;
			else if(a->GetEstimate() < b->GetEstimate())
				return a->op < b->op;
			else return false;
		}
		else return false;
	}
};

int Cell::DestCol = 0;
int Cell::DestRow = 0;

typedef vector<Cell> RowType;
typedef vector<RowType> MatrixType;
typedef priority_queue<Cell*,vector<Cell*>,CellCompare> PQueue;

class Maze : public MatrixType
{
private:
	int m_row,m_col;
public:
	Maze( int row, int col )
		:MatrixType( row, *(new RowType(col)) )
	{
		Maze& M = *this;
		m_row = this->size();
		m_col = row>0?M[0].size():0;
		for( int r = 0; r < m_row; ++r)
			for( int c=0; c < m_col;++c)
				M[r][c].SetCoordinate(r,c);
	}
	int RowCount()const{return m_row;}
	int ColCount()const{return m_col;}
};
const char OP[]="DLRU";
int AStar( Maze& M )
{
	const static int direct[4][3] = {{1,0,0/*D*/},{0,-1,1/*L*/},{0,1,2/*R*/},{-1,0,3/*U*/}};
	PQueue Q;
	M[0][0].NowStep = 0;
	Q.push( &M[0][0] );
	Cell* Dest = &M[ M.RowCount()-1 ][ M.ColCount()-1];
	
	while( !Q.empty() )
	{
		Cell* C = Q.top();
		Q.pop();
		if( C->IsVisited ) continue;
		C->IsVisited = true;
		for( int i = 0; i < 4; ++i )
		{
			int r = C->RowIndex() + direct[i][0];
			int c = C->ColIndex() + direct[i][1];
			if( r>=0 && r < M.RowCount() && c >= 0 && c < M.ColCount() )
			{
				Cell* nextC = &M[r][c];
				if( nextC->IsVisited ) continue;
				if( nextC->IsOpened )
				{
					if( nextC->NowStep > C->NowStep+1)
					{
						nextC->NowStep = C->NowStep+1;
						nextC->prevSite = C;
						nextC->op = direct[i][2];
						Q.push( nextC );
					}
				}
				else
				{
					nextC->IsOpened = true;
					nextC->NowStep = C->NowStep + 1;
					nextC->prevSite = C;
					nextC->op = direct[i][2];
					Q.push( nextC );
				}
				if( nextC == Dest ) return nextC->NowStep;
			}
		}
	}
	return -1;
}

int main(int argc, char** argv) {
	cin >> Cell::DestRow >> Cell::DestCol;
	Maze M( Cell::DestRow,Cell::DestCol );
	char *rowSet = new char[M.ColCount()+1];
	for( int i = 0; i < M.RowCount(); ++i)
	{
		cin >> rowSet;
		for( int j = 0; j < M.ColCount();++j)
		{
			M[i][j].IsVisited = (rowSet[j]=='1');
		}
	}
	delete rowSet;
	int step = AStar( M );
	char *opSet = new char[step+1];
	opSet[ step ]=0;
	Cell* C = &M[M.RowCount()-1][M.ColCount()-1]; 
	for( int i = 0; i < step; ++i )
	{
		opSet[step-i-1] = OP[C->op];
		C = C->prevSite;
	}
	cout <<step<<endl
		<< opSet;
	delete opSet;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值