joj 1113 The Game

                                                         The Game

joj 1113 The Game_第1张图片
这道题是为了让折线数最小,跟先到达没有必然关系。
5 4
XXXXX
X  XX
XX  
X XXX
2 1 5 4
0 0 0 0
0 0
比如这个就应该是4,而不是最先到达的5。
同时不同折线经过相同的点,例如:
6 5
XXXX X
X  X X
XX X X
XX   X
XXXXXX
2 1 5 5
应该是3

#include "iostream"
#include "cstring"
#include "cstdio"
#include "queue"
using namespace std;
#define size 79

int row, col;
int x1, y1, x2, y2;
int line[size][size];	//line[i][j]为开始牌到i,j的折线数,同时起到一方面可以判段是否被访问过
char grid[size][size];
int Max;
struct piece{
	int x1, y1, step;
	int direction;	//上一步的方向,1为上下走,2为左右走
};
queue<piece> Q;

void fuzhi(int x1, int y1, int step, int direction, int dir){
	//不能越界,不能有纸牌,为了每行不太长,分 几次判断
	if(!(x1 >= 0 && x1 <= row + 1 && y1 >= 0 && y1 <= col + 1) || step >= Max)
		return;
	if(line[x1][y1] && step >= line[x1][y1])	//如果被访问过,而且现在的折数比以前到达的折数大,这是剪枝方法
		return;
	if(grid[x1][y1] != 'X' || (x1 == x2 && y1 == y2)){
		piece p2;
		p2.x1 = x1 ;
		p2.y1 = y1;
		p2.direction = dir;
		p2.step = step;
		if(direction != dir)	//初值direction为0, 一走就要折数加1,这是合理的
			p2.step++;
		line[x1][y1] = p2.step;
		Q.push(p2);
	}
}

int bfs(){
	piece p1;
	p1.direction = 0;		//初始方向为0
	p1.x1 = x1;
	p1.y1 = y1;
	p1.step = 0;
	Q.push(p1);
	Max = 0xffffff;
	while(!Q.empty()){
		p1 = Q.front();
		Q.pop();
		if(p1.x1 == x2 && p1.y1 == y2){
			if(Max > p1.step)
				Max = p1.step;
			line[x2][y2] = 0;	//给下一次到达它的留机会,不然下次没有人能够到达它了
		}
		else{
			fuzhi(p1.x1 - 1, p1.y1, p1.step, p1.direction, 1);//往上走
			fuzhi(p1.x1 + 1, p1.y1, p1.step, p1.direction, 1);//往下走
			fuzhi(p1.x1, p1.y1 - 1, p1.step,  p1.direction, 2);//往左走
			fuzhi(p1.x1, p1.y1 + 1, p1.step,  p1.direction, 2);//往右走
		}
	}
	if(Max == 0xffffff)
		return -1;
	return Max;
}

int main(){
//	freopen("in.txt", "r", stdin);
	int i, iCase = 1;					//iCase测试例个数
	while(cin>>col>>row && col && row){
		memset(grid, ' ', sizeof(grid));
		getchar();
		for(i = 1; i <= row; i++){		//接受数据
			gets(grid[i] + 1);
		}

		int pair = 1;
		cout<<"Board #"<<iCase++<<":"<<endl;
		while(cin>>y1>>x1>>y2>>x2 && x1 && x2 && y1 && y2){
			memset(line, 0, sizeof(line));
			while(!Q.empty())
				Q.pop();
			int temp = bfs();
			if(temp != -1)
				cout<<"Pair "<<pair++<<": "<<temp<<" segments."<<endl;
			else
				cout<<"Pair "<<pair++<<": "<<"impossible."<<endl;
		}
		cout<<endl;
	}
	return 0;
}


你可能感兴趣的:(宽度搜索)