pku1376Robot


この主な経典の広捜、一般的な方法は1つの配列を定義して各位置の4つの面がアクセスされるかどうかを表して、それからキューですればいいです!ただ隣は歩けないので注意!コードは以下の通りです(他の人を参照すると、構造がはっきりしています!)
/*Problem: 1376  User: qjklw 
Memory: 208K  Time: 94MS 
Language: C++  Result: Accepted 
*/
#include <iostream>
#include <queue>
using namespace std;

#define maxint 51
struct Point                  
{ 
	int x, y, length, face;
	Point(int x1, int y1, int length1, int face1)
	{
		x=x1;      
		y=y1;
		length=length1;                     
		face=face1;
	}
};
int g[maxint][maxint];
int v1x, v2x, v1y, v2y, ori, M, N;                     
int position[4][2]={{0,1}, {1,0}, {0,-1}, {-1, 0}} ;
bool visit[maxint][maxint][4];

void input()
{
    int i, j, k ;
	char a[10] ;
	 
	for(i=0; i<M; i++)
		for(j=0; j<N; j++)
			scanf("%d",&g[i][j]) ;

	for(i=0; i<M; i++)
		for(j=0; j<N; j++)
			for(k=0; k<4; k++)
				visit[i][j][k]=false;
    
	scanf("%d%d%d%d", &v1x, &v1y, &v2x, &v2y) ;
	v1x--, v2x--, v1y--,  v2y--;

    scanf("%s",a) ;
	if(!strcmp(a,"south"))       ori=1 ;
	else if(!strcmp(a,"east"))   ori=0 ;     
	else if(!strcmp(a,"west"))   ori=2 ;
	else                         ori=3 ;
}

void solve()
{
	queue<Point> q;
	Point p(v1x, v1y, 0, ori);
	q.push(p) ;

    int Length=-1, tx, ty, i, tlength, tface ;
	while(!q.empty())
	{
		Point top=q.front();
		if(top.x==v2x&&top.y==v2y)
		{
			Length=top.length;
			break;
		}

        tx=top.x;
		ty=top.y;
		tlength=top.length;
		for(i=-1; i<=1; i+=2)
		{
			tface=(top.face+i+4)%4 ;
			if(visit[tx][ty][tface])
				continue;
			Point tp(tx, ty, tlength+1, tface) ;
			q.push(tp) ;
			visit[tx][ty][tface]=true ;
		}

		tface=top.face;
		tlength=top.length;
		for(i=1; i<=3; i++)
		{
			tx=top.x+i*position[tface][0];
			ty=top.y+i*position[tface][1];
			if(visit[tx][ty][tface])
				continue;
			if(tx<0||tx>=M-1||ty<0||ty>=N-1 || g[tx][ty]||g[tx+1][ty]||g[tx][ty+1]||g[tx+1][ty+1])
				break;
			Point tp(tx, ty, tlength+1, tface);
			q.push(tp);
			visit[tx][ty][tface]=true;
		}

		q.pop();
	}

	printf("%d
", Length) ; } int main() { while(scanf("%d%d", &M, &N)) { if(!M&&!N) break ; input() ; solve() ; } return 0; }

方法2、直接題意を満たす点をキューに入れ、最初の点を後ろに回してこそ意味があり、残りの点を後ろに回して浪費する.この方法ではキューが溢れやすく、私は何度もwaをして、何時間も調べて、最後にジャンプの次のポイントの要求を厳しくしました(次のポイントがジャンプしたことがないか、同じ歩数で到着したが方向が違うときだけキューに参加します)、過ぎました.
/*Source Code

Problem: 1376  User: qjklw 
Memory: 324K  Time: 32MS 
Language: C++  Result: Accepted 
*/
#include <iostream>
using namespace std ;

const int maxint=10000;
struct Vertex
{
	int x, y, length, face ;
}vertex[maxint] ;

int graph[51][51] ;
int way[4][3][2]={ {{0,1},{0,2},{0,3}}, {{1,0},{2,0},{3,0}}, {{0,-1},{0,-2},{0,-3}}, {{-1,0},{-2,0},{-3,0}}} ;

int M, N, v1x, v2x, v1y, v2y, ori ;
void input()
{
	int i, j ;
	char a[10] ;
	 
	for(i=0; i<M; i++)
		for(j=0; j<N; j++)
			scanf("%d",&graph[i][j]) ;
    
	scanf("%d%d%d%d", &v1x, &v1y, &v2x, &v2y) ;
	v1x--, v2x--, v1y--,  v2y--;

    scanf("%s",a) ;
	if(!strcmp(a,"south"))       ori=1 ;
	else if(!strcmp(a,"east"))   ori=0 ;     
	else if(!strcmp(a,"west"))   ori=2 ;
	else                         ori=3 ;
}

void solve()
{
	int head=0, tail=0, i, k, m, n, p, flag=0;

    if(v1x==v2x && v1y==v2y)
	{              
		printf("0
") ; return ; } vertex[head].x=v1x; vertex[head].y=v1y; vertex[head].face=ori; vertex[head++].length=0; while(head!=tail) { k=tail; tail=(tail+1)%maxint; for(i=0;i<3;i++) { m = vertex[k].x+way[vertex[k].face][i][0] ; n = vertex[k].y+way[vertex[k].face][i][1] ; p = vertex[k].length ; if(graph[m+1][n]!=1||graph[m][n+1]!=1||graph[m+1][n+1]!=1|| m<M-1||m>=0 || n<N-1||n>=0) break; if(!graph[m][n]||(graph[m][n]==p+1&&graph[m][n]!=1))// , { if(m==v2x && n==v2y) { printf("%d
", p+1) ; return; } vertex[head].x=m; vertex[head].y=n; vertex[head].length=p+1; vertex[head].face=vertex[k].face; head=(head+1)%maxint; } else break ; } if(!graph[vertex[k].x][vertex[k].y]) { vertex[head].x=vertex[k].x; // vertex[head].y=vertex[k].y; vertex[head].length=vertex[k].length+1; vertex[head].face=(vertex[k].face+1)%4; head=(head+1)%maxint; vertex[head].x=vertex[k].x; // vertex[head].y=vertex[k].y; vertex[head].length=vertex[k].length+1; vertex[head].face=(vertex[k].face+3)%4; head=(head+1)%maxint; if(!flag)// ( ). { flag=1; vertex[head].x=vertex[k].x; vertex[head].y=vertex[k].y; vertex[head].length=vertex[k].length+2; vertex[head].face=(vertex[k].face+2)%4; head=(head+1)%maxint; graph[vertex[k].x][vertex[k].y]=2; continue; } graph[vertex[k].x][vertex[k].y]=vertex[k].length+1; } } printf("-1
") ; } int main() { while(scanf("%d%d", &M, &N)) { if(!M&&!N) break ; input() ; solve() ; } return 0 ; }