POJ_4115(有穿墙次数的BFS算法)

POJ_4115,有穿墙次数(能量)的BFS题目,代码有所参考

#include 
#include 
using namespace std;
struct point{
	//该点的行列,到达用时,剩余能量,能否不消耗能量通过 
	int r,c,alltime,chance;
	bool cango;
}points[200][200];
queue <point> q;
int row,col,endr,endc;

int bfs(){
	while(!q.empty()){
		point curr=q.front();
		q.pop();
		if(curr.r==endr && curr.c==endc)	return curr.alltime;
		int choose[4][2]={{curr.r-1,curr.c},{curr.r+1,curr.c},{curr.r,curr.c-1},{curr.r,curr.c+1}};
        for(int i=0;i<4;i++){
        	int nextr=choose[i][0],nextc=choose[i][1];
//不同于普通BFS,除了边界这里检查的不是该点是否访问过,而是要到达该点的能量是否大于之前的
//原因是若之前该点的能量小于这次的,说明上次路径未能到达终点,不然到达该点的能量只会相等或更小(又消耗了能量)
//而如果上次就能到达终点的话,把这个点处理后不会对结果有影响(因为该点只走一次就到达终点,不会再返回来走) 
        	if(nextr>=0 && nextc>=0 && nextr<row && nextc<col && curr.chance>points[nextr][nextc].chance){
        		points[nextr][nextc].alltime=curr.alltime+1;
        		points[nextr][nextc].chance=curr.chance;
        		if(points[nextr][nextc].cango)	q.push(points[nextr][nextc]);
        		else if(curr.chance>0){
    				points[nextr][nextc].chance--;
    				q.push(points[nextr][nextc]);
				}
            }
		}  
    }
    return -1;
}

int main(){
	int chance;		cin>>row>>col>>chance;
	for(int i=0;i<row;i++)
		for(int j=0;j<col;j++){
			points[i][j].r=i;
			points[i][j].c=j;
			points[i][j].alltime=0;
			//初始能量是-1(与上方BFS对应) 
			points[i][j].chance=-1;
			char c;		cin>>c;
			if(c=='#')	points[i][j].cango=0;
			else{
				points[i][j].cango=1;
				if(c=='@'){
					points[i][j].chance=chance;
					q.push(points[i][j]);
				}
				else if(c=='+'){
					endr=i;
					endc=j;
				}
			}
		}
	cout<<bfs();
} 

你可能感兴趣的:(OJ练习)