拐弯 ( 洛谷 P1649 [USACO07OCT]障碍路线Obstacle Course )

版权声明:欢迎转载欢迎评论! https://blog.csdn.net/rabbit_ZAR/article/details/82873087

题目:
障碍路线

题目描述
N*N ( 1 <= N <= 100 ) 方格中, 'x' 表示不能走的格子, '.'表示可以走的格子。
卡门很胖,故而不好转弯。现在要从A点走到B点,请问最少要转90度弯几次?
只可以上、下、左、右四个方向行走,并且不能走出这些格子之外。
开始和结束时的方向可以任意。

输入输出格式
输入格式:
第一行一个整数: N ,下面N行,每行N个字符,只出现字符: '.' , 'x', 'A', 'B' ,
表示上面所说的矩阵格子,每个字符后有一个空格(包括每一行的最后)。
2 <= N <= 100

输出格式:
一个整数,最少转弯次数。如果不能到达,输出-1 。

输入输出样例
输入样例#13
. x A
. . .
B x .
输出样例#12

思路:
最开始想直接一格一格地bfs,写了下复杂度爆了。
然后想把每个节点到它不拐弯就可以到达的节点连接,建一个无向图。
然后在这个无向图上bfs就好了。

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

#define maxn 100
#define inf (1<<30)
#define read(x) scanf("%d",&x);

struct Pair {
	int x,y;
	Pair() {}
	Pair(int xx,int yy) {
		x=xx,y=yy;
	}
	bool operator == (const Pair& oth) const {
		return x==oth.x&y==oth.y;
	}
};

struct Node {
	Pair dr;
	int stp,p;
	Node() {};
	Node(int x,int y,int ss,int pp) {
		dr=Pair(x,y);
		stp=ss,p=pp;
	}
	Node(Pair dd,int ss,int pp) {
		dr=dd;
		stp=ss,p=pp;
	}
};

const int m1[5]= {0,0,0,1,-1};
const int m2[5]= {0,1,-1,0,0};

int n;
bool a[maxn+5][maxn+5];
Pair st,ed;
int s,t;

vector<int> g[maxn*maxn+5];

void readchar(char& x) {
	while((~scanf("%c",&x))&&(x!='.'&&!isalpha(x)));
}

void readin() {
	read(n);
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			char x;
			readchar(x);
			if(x=='x') a[i][j]=1;
			else a[i][j]=0;
			if(x=='A') st=Pair(i,j);
			else if(x=='B') ed=Pair(i,j);
		}
	}
}

int getid(int x,int y) {
	return (x-1)*n+y;
}

void make() {
	s=getid(st.x,st.y),t=getid(ed.x,ed.y);
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=n;j++) {
			if(a[i][j]) continue;
			for(int k=i+1;k<=n;k++) {
				if(a[k][j]) break;
				g[getid(i,j)].push_back(getid(k,j));
				g[getid(k,j)].push_back(getid(i,j));
			}
			for(int k=j+1;k<=n;k++) {
				if(a[i][k]) break;
				g[getid(i,j)].push_back(getid(i,k));
				g[getid(i,k)].push_back(getid(i,j));
			}
		}
	}
}

queue<Pair> que;
int b[maxn*maxn+5];

int bfs(){
	que.push(Pair(s,-1));
	b[s]=true;
	while(!que.empty()) {
		Pair x=que.front();que.pop();
		for(int i=0;i<g[x.x].size();i++) {
			int y=g[x.x][i];
			if(b[y]) continue;
			if(y==t) return x.y+1;
			b[y]=true;
			que.push(Pair(y,x.y+1)); 
		}
	}
	return -1;
}

int main() {
	readin();
	make();
	int ans=bfs();
	printf("%d",ans);
	return 0;
}

PS:博客400祝贺QwQ~

猜你喜欢

转载自blog.csdn.net/rabbit_ZAR/article/details/82873087