// align.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"


#include <vector>

template<int width>
class v :public std::vector<int>{
public:

	v(int n){
		resize(width*n);
	}

	int * operator [] (int n){
		return &at(n*width);
	}

};


int _tmain(int argc, _TCHAR* argv[])
{


	v<2> x(2);

	int i = x[0][0];

	x[0][0] = 1;
	x[0][1] = 2;
	x[1][0] = 3;
	x[1][1] = 4;

	return 0;
}
      • -
// align.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"


#include <vector>

class v :public std::vector<int>{
public:
	int width;
	v(int w,int h)
		:width(w)
	{
		resize(w*h);
	}

	int * operator [] (int n){
		return &at(n*width);
	}

};


int _tmain(int argc, _TCHAR* argv[])
{


	v x(2,2);

	int i = x[0][0];

	x[0][0] = 1;
	x[0][1] = 2;
	x[1][0] = 3;
	x[1][1] = 4;

	return 0;
}

ソース

家に手頃なLinux環境がなかったのでVisual Studio 2008体験版を落とした
zの袋小路の刈り取りは、狩り取れなくなるまで、やるべきだけど、面倒なので2でスキップ。
本当はほかと同じでmemcmpで前回と差がなくなるまで回すと総当たりでよろし

// route.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>

enum {
	BLOCK = -1,
	START =  1,
	END   = -2,
	CRLF   = -3,
	WALK   = -4
};

#define READMAX 50


void walk(int *dst,int src){
	if(*dst == 0 ){
		*dst = src+1;
	}
	if(*dst > src+1){
		*dst = src + 1;
	}
}

int map[READMAX][READMAX] ;
int map2[READMAX][READMAX] ;
int line = 0;


void print(){
	for(int y = 0 ; y < line ; y++)
	{
		for(int x = 0 ; x < READMAX ; x++)
		{
			switch(map[y][x]){
				case BLOCK:
					printf(" * ");
					break;
				case START:
					printf(" S ");
					break;
				case END:
					printf(" G ");
					break;
				case WALK:
					printf(" $ ");
					break;
				case CRLF:
					printf("\n");
					x = READMAX;
					break;
				case 0:
					printf("   ");
					break;
				default:
					printf("%2x ",map[y][x]);
					break;
			}
		}
	}
}


void printAns(){
	for(int y = 0 ; y < line ; y++)
	{
		for(int x = 0 ; x < READMAX ; x++)
		{
			switch(map[y][x]){
				case BLOCK:
					printf("*");
					break;
				case START:
					printf("S");
					break;
				case END:
					printf("G");
					break;
				case WALK:
					printf("$");
					break;
				case CRLF:
					printf("\n");
					x = READMAX;
					break;
				case 0:
				default:
					printf(" ");
					break;
			}
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{

	memset(map,0,sizeof(map));


	//Read in data
	while(true){
		char buf[READMAX];
		int i;
		char * ret = fgets(buf,READMAX,stdin);
		if(ret==NULL){
			break;
		}
		if(buf[0]==0x04){
			break;
		}
		int len = strlen(buf);
		for(i = 0 ; i < len ; i++){
			if(buf[i]=='*'){
				map[line][i] = BLOCK;
			}else 
			if(buf[i]=='S'){
				map[line][i] = START;
			}else 
			if(buf[i]=='G'){
				map[line][i] = END;
			}else{
				map[line][i] = 0;
			}
		}
		map[line][i] = CRLF;
		line++;
	}
	
	int steps = 0;

	//walking all route.
	while(true){
		printf("Step %d \n",++steps);
		
		memcpy(map2,map,sizeof(map));

		for(int y = 1 ; y < line -1 ; y++)
		{
			for(int x = 1 ; x < READMAX-1 ; x++)
			{
				if(map[y][x] == 0){
					continue;
				}
				if(map[y][x] == BLOCK){
					map2[y][x]=map[y][x];
					continue;
				}
				if(map[y][x] == CRLF){
					map2[y][x]=map[y][x];
					break;
				}
				if(map[y][x] == END){
					map2[y][x]=map[y][x];
					continue;
				}
				walk(&map2[y-1][x ],map[y][x]);
				walk(&map2[y ][x-1],map[y][x]);
				//walk(&map2[y ][x ],map[y][x]);
				walk(&map2[y ][x+1],map[y][x]);
				walk(&map2[y+1][x ],map[y][x]);
			}
		}
		if(memcmp(map,map2,sizeof(map))==0){
			break;
		}
		memcpy(map,map2,sizeof(map));
		print();
	}

	memcpy(map,map2,sizeof(map));

	//check min route.
	for(int z = 0 ; z < 2 ; z ++){
		for(int y = 1 ; y < line -1 ; y++)
		{
			for(int x = 1 ; x < READMAX-1 ; x++)
			{
				if(map[y][x] <= 1){
					continue;
				}

				if( map[y-1][x] == END ||
					map[y ][x-1] == END ||
					map[y+1][x] == END ||
					map[y ][x-1] == END
					){
						continue;
				}

				if(!(
					map[y-1][x] == map[y][x]-1 ||
					map[y ][x-1] == map[y][x]-1 ||
					map[y+1][x] == map[y][x]-1 ||
					map[y ][x+1] == map[y][x]-1))
				{
						map[y][x] = 0;
						continue;
				}
				if(!(
					map[y-1][x] == map[y][x]+1 ||
					map[y ][x-1] == map[y][x]+1 ||
					map[y+1][x] == map[y][x]+1 ||
					map[y ][x+1] == map[y][x]+1))
				{
						map[y][x] = 0;
						continue;
				}
			}
		}
	}
	printf("Minimum route \n");
	print();

	//walk start to end ... no end to start haha.

		for(int y = 1 ; y < line -1 ; y++)
		{
			for(int x = 1 ; x < READMAX-1 ; x++)
			{
				if(map[y][x] != END){
					continue;
				}
				//found goal.

				while(true){

					int min = 0x7FFFFFFF;
					//find old step.
					if(min > map[y-1][x] && map[y-1][x]>0) min = map[y-1][x];
					if(min > map[y][x-1] && map[y  ][x-1]>0) min = map[y][x-1];
					if(min > map[y+1][x] && map[y+1][x]>0) min = map[y+1][x];
					if(min > map[y][x+1] && map[y  ][x+1]>0) min = map[y][x+1];

					//move to old.
					if(min == map[y-1][x] )  y--;
					else if(min == map[y  ][x-1] )  x--;
					else if(min == map[y+1][x] )  y++;
					else if(min == map[y  ][x+1] )  x++;

					if(map[y][x] == START){
						x = y = READMAX;
						break;
					}

					map[y][x] = WALK;
					print();

				}
			}
		}

	//memcpy(map,map2,sizeof(map));

	printf("result \n");
	printAns();



	getchar();


	return 0;
}



ちなみに、スタックを使っても良ければ、前回移動した場所を覚えて、そこだけ再評価すると早い。
また、となりがゴールだったら、そこで評価を辞めても大概の場合は良い。ワープでも無い限りは、それが最短だから。