java迷路の問題-移動距離(第6回ブルーブリッジカップの本当の質問)

最初にタイトルのスクリーンショットを添付してください

ここに画像の説明を挿入
この問題と古典的な迷路の問題との難しさは、配列の割り当ての確立と入力値の位置の検出にあります。これら2つが解決された後、古典的なdfsアルゴリズムを使用して最短距離を計算できます。

最初のステップ:特別な配列を作成します。

		w = in.nextInt();
//		n = in.nextInt();
		int num=1;
		for(int i=1;i<=10;i++) {
    
    
			if((i&1)==1) {
    
          //判断是否是奇数行
				for(int j=1;j<=w;j++)
			a[i][j]=num++;     //顺序赋值
			}
			else {
    
    
				for(int j=w;j>0;j--)  //逆序赋值
					a[i][j]=num++;  
			}
		}

ステップ2:割り当て後、2つの数値mとnを入力し、配列をトラバースしてmとnが配置されている行と列を見つけます。つまり、開始位置と目標位置を見つけます。

		m=in.nextInt();
		n=in.nextInt();
			for(int i=0;i<10;i++) {
    
    
				for(int j=0;j<=w;j++)
				{
    
    	if(a[i][j]==m) {
    
     startx=i; starty=j;}
					if(a[i][j]==n) {
    
     p=i;q=j;}
				}
			}

次に、最も一般的に使用されるdfsアルゴリズムの1つを使用して開始位置と目標位置の間の距離を計算することで、次のステップははるかに簡単になります。

	public static void dfs(int x,int y,int step) {
    
    
		if(x==p && y==q)
		{
    
    
			if(step<min)
				min=step;
			return;
		}
		for(int i=0;i<4;i++) {
    
    
			int tx = x+dx[i];
			int ty = y+dy[i];
			if(tx<=minx&&ty<=w&&tx>=0&&ty>=0)
			if(v[tx][ty]==0) {
    
    
				v[tx][ty]=1;
				dfs(tx,ty,step+1);
				v[tx][ty]=0;
			}
		}
	}

異なる数の列を入力して得られる配列は非常に異なるため、txの範囲はminxによって制限されます
。minxは、開始位置とターゲット位置の最大行数の値を取ります。

		minx=Math.max(startx, p);

完全なコードを添付してください:

package six;

import java.util.Scanner;

public class text4 {
    
    
//移动距离
	static int a[][] = new int [50][50];
	static int v[][] = new int [50][50];
	static int p,q,startx,starty;
	static int min=999;
	static int w,m,n;
	static int dx[] = {
    
    0,1,0,-1};
	static int dy[] = {
    
    1,0,-1,0};
	static int minx;
	public static void dfs(int x,int y,int step) {
    
    
		if(x==p && y==q)
		{
    
    
			if(step<min)
				min=step;
			return;
		}
		for(int i=0;i<4;i++) {
    
    
			int tx = x+dx[i];
			int ty = y+dy[i];
			if(tx<=minx&&ty<=w&&tx>=0&&ty>=0)  //这里要加minx是因为简约算法的路径
			if(v[tx][ty]==0) {
    
    
				v[tx][ty]=1;
				dfs(tx,ty,step+1);
				v[tx][ty]=0;
			}
		}
	}
	public static void main(String[] args) {
    
    
		Scanner in  = new Scanner(System.in);
		w = in.nextInt();
//		n = in.nextInt();
		int num=1;
		for(int i=1;i<=10;i++) {
    
    
			if((i&1)==1) {
    
          //判断是否是奇数行
				for(int j=1;j<=w;j++)
			a[i][j]=num++;     //顺序赋值
			}
			else {
    
    
				for(int j=w;j>0;j--)  //逆序赋值
					a[i][j]=num++;  
			}
		}
//		for(int i=0;i<10;i++) {
    
    
//			for(int j=0;j<=w;j++)
//				System.out.print(a[i][j]+" ");
//			System.out.println("");
//		}
		m=in.nextInt();
		n=in.nextInt();
			for(int i=0;i<10;i++) {
    
    
				for(int j=0;j<=w;j++)
				{
    
    	if(a[i][j]==m) {
    
     startx=i; starty=j;}
					if(a[i][j]==n) {
    
     p=i;q=j;}
				}
			}
//        System.out.println(startx+" "+starty+" " +p+" "+q);
		minx=Math.max(startx, p);
        dfs(startx,starty,0);
		System.out.println(min);
	}
}

2020.12.22

おすすめ

転載: blog.csdn.net/weixin_44919936/article/details/109585615