计算m-n楼的最短距离

[问题描述]


 X星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为1,2,3...当排满一行时,从下一行相邻的楼往反方向排号。比如:当小区排号宽度为6时,开始情形如下:
 1  2  3  4  5  6

 12 11 10 9  8  7

 13 14 15 .....

 我们的问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离(不能斜线方向移动)
 输入为3个整数w m n,空格分开,都在1到10000范围内
 要求输出一个整数,表示m n 两楼间最短移动距离。

 [样例输入]      [样例输出]

 6 8 2               4

 4 7 20             5

 [我的答案]

public class MyAnswer {
	public static void main(String[] args) {
		int w;
		int m;
		int n;
		int m_hang=0;
		int m_lie;
		int n_hang=0;
		int n_lie;
		Scanner sc=new Scanner(System.in);
		w=sc.nextInt();m=sc.nextInt();n=sc.nextInt();
		
		//m小,n大
		if(m>n) {
			int x=m;
			m=n;
			n=x;
		}
		
		//判断m在第几行
		int i=1;
		Boolean b=true;
		while(b) {
			if(w*i>=m) {
				m_hang=i;
				b=false;
			}else {
				i++;
			}
		}
		if(m_hang%2==0) {
			if(m%w!=0)
				m_lie=w-(m%w)+1;
				else
					m_lie=1;
			
		}else {
			m_lie=m%w;
			if(m_lie==0) {
				m_lie=w;
			}
		}
		
		System.out.println(m_hang+" "+m_lie+" ");
		
		//判断n第几行
		b=true;
		while(b) {
			if(w*i>=n) {
				n_hang=i;
				b=false;
			}else {
				i++;
			}
		}
		
		if(n_hang%2==0) {
			if(n%w!=0)
			n_lie=w-(n%w)+1;
			else
				n_lie=1;
		}else {
			n_lie=n%w;
			if(n_lie==0) {
				n_lie=w;
			}
		}
		System.out.println(n_hang+" "+n_lie+" ");
		
		int distance_hang=n_hang-m_hang;
		int distance_lie=n_lie-m_lie;
		if(distance_lie<0) {
			distance_lie=-distance_lie;
		}
		System.out.println(distance_hang+" "+distance_lie+" ");
		System.out.println(distance_hang+distance_lie);

	}

}

本题的思路很清晰,只要把距离分成行距离和列距离即可。但是在做的时候,需要注意很多:

1.在判断行的时候,第一行的条件必须考虑。本人一开始的判断语句,直接跳过了第一行。

2.在判断列的时候,需要注意,取余为0的情况要单独列出来。同时在两列相减的时候,需要+1。

 [更好答案]

import java.util.Scanner;

public class Answer {

		  public static void main(String[] args) {

		    Scanner sc = new Scanner(System.in);
		    int w = sc.nextInt();
		    int m = sc.nextInt();
		    int n = sc.nextInt();
		    
		    int bigger = Integer.max(m, n);
		    int smaller = Integer.min(m, n);
		    int r1 = bigger % w == 0 ? (bigger / w - 1) : bigger / w;//大数的行号
		    
		    int c1;//计算列号
		    if ((r1 & 1) == 1) {//第偶数行,顺着走
		      c1 = (w - bigger % w) % w;
		    } else {//奇数行
		      c1 = (bigger % w - 1 + w) % w;
		    }

		    int r2 = smaller % w == 0 ? (smaller / w - 1) : smaller / w;//小数的行号
		    int c2;
		    if ((r2 & 1) == 1) {//第偶数行,顺着走
		      c2 = (w - smaller % w) % w;
		    } else {//奇数行
		      c2 = (smaller % w - 1 + w) % w;
		    }
		    System.out.println(Math.abs(r1 - r2) + Math.abs(c1 - c2));
		  }

}

别人的答案里面,写的比我的简洁,思路是一样的。优化点有一下三点:

1.在判断行的时候,他直接用了三元运算,很简洁。

2.比较m和n的大小时,直接使用了函数max和min。

3.最终取绝对值,他用了abs函数。

<think>好的,我现在需要帮助用户修改他们的Dijkstra算法代码,以便输出从1号点到所有其他节点(1到n)的最短路径。用户提供的代码片段是Dijkstra的核心部分,用于寻找当前未处理的最小距离节点。但用户现在希望输出所有最短路径,而不仅仅是到n号点的。 首先,我需要确认用户的需求。用户可能正在实现Dijkstra算法,但当前的代码可能只输出了到n号点的最短路径,而他们需要的是从1号点到每个节点的路径,包括1到1、1到2,直到1到n。因此,用户需要修改代码,使其遍历并存储所有节点的最短距离,并在最后输出所有结果。 接下来,我需要回顾Dijkstra算法的基本结构。通常,算法会初始化一个距离数组dist,其中dist[1] = 0,其他节点为无穷大。然后,每次选择未处理的最近节点,更新其邻居的距离。最后,dist数组中的值就是从起点到各点的最短距离。 用户提供的代码段是选择下一个处理节点的部分。现在的问题是如何在算法结束后输出所有dist的值。可能用户当前的代码只输出了dist[n],而他们需要遍历整个dist数组,从1到n每个节点都输出。 可能的解决方案是在算法结束后,循环遍历dist数组,从1到n,逐个输出。需要注意处理无法到达的情况,比如当dist[i]仍然是无穷大时,可能需要输出-1或其他提示信息。 此外,我需要考虑用户代码中可能存在的初始化问题。例如,是否在算法开始时正确初始化了dist数组,起点是否为1号点,节点编号是否从1开始。这些都可能影响最终的输出结果。 用户可能没有意识到,在标准的Dijkstra实现中,dist数组已经包含了所有节点的最短路径信息,只需要在最后打印出来即可。因此,问题可能出在输出部分,而不是算法本身。需要指导用户添加输出循环,并在适当的位置处理无穷大的情况。 另外,需要确保在输出时,起点到自身的距离是否正确处理。例如,dist[1]应该为0,如果在初始化时已经正确设置,那么直接输出即可。 最后,可能需要提醒用户关于节点数和边数的问题,确保数据输入正确,比如在输入边的时候是否处理了重边或者自环,但这可能超出当前问题的范围。当前主要关注的是如何修改输出部分。 总结一下,用户的代码可能缺少遍历输出dist数组的步骤,只需在算法结束后循环输出即可,同时处理无穷大的情况。</think>要输出 **1号点到所有1~n号节点的最短路径**,只需在 Dijkstra 算法结束后,遍历 `dist[]` 数组即可。以下是具体修改方法及完整代码示例: --- ### **修改后的代码逻辑** 1. **初始化时确保 `dist[1] = 0`**(起点到自己的距离为0)。 2. **运行 Dijkstra 算法**,计算从1号点到所有节点的最短路径。 3. **遍历 `dist[]` 数组**,输出从1号点到每个节点的最短距离--- ### **代码示例(C++)** ```cpp #include <iostream> #include <cstring> using namespace std; const int N = 510; int g[N][N]; // 邻接矩阵存图 int dist[N]; // 存储1号点到各点的最短距离 bool st[N]; // 标记节点是否已确定最短路径 int n, m; // n节点数, m边数 void dijkstra() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; // 初始化起点距离为0 for (int i = 0; i < n; i++) { // 遍历n次 int t = -1; for (int j = 1; j <= n; j++) { if (!st[j] && (t == -1 || dist[j] < dist[t])) { t = j; } } st[t] = true; // 标记为已处理 // 更新邻接节点的最短距离 for (int j = 1; j <= n; j++) { dist[j] = min(dist[j], dist[t] + g[t][j]); } } } int main() { cin >> n >> m; memset(g, 0x3f, sizeof g); // 初始化邻接矩阵为无穷大 // 读入边信息 while (m--) { int a, b, c; cin >> a >> b >> c; g[a][b] = min(g[a][b], c); // 处理重边,保留最短边 } dijkstra(); // 输出1号点到所有1~n号节点的最短距离 for (int i = 1; i <= n; i++) { if (dist[i] == 0x3f3f3f3f) { cout << "1号点无法到达节点 " << i << " (距离为INF)" << endl; } else { cout << "1号点到节点 " << i << " 的最短距离: " << dist[i] << endl; } } return 0; } ``` --- ### **关键修改说明** 1. **初始化 `dist[1] = 0`** - 确保起点到自己的距离正确初始化为0。 2. **遍历输出 `dist[]` 数组** - 在 `dijkstra()` 执行后,通过循环 `for (int i = 1; i <= n; i++)` 输出所有节点的最短距离- 处理无法到达的情况:如果 `dist[i]` 仍为 `0x3f3f3f3f`(表示无穷大),说明1号点无法到达该节点。 --- ### **输入输出示例** 假设输入: ``` 4 5 1 2 2 1 3 4 2 3 1 2 4 5 3 4 3 ``` 输出: ``` 1号点到节点 1 的最短距离: 0 1号点到节点 2 的最短距离: 2 1号点到节点 3 的最短距离: 3 (路径:1→2→3) 1号点到节点 4 的最短距离: 6 (路径:1→2→3→4) ``` --- ### **注意事项** 1. **节点编号范围**:代码假设节点从1开始编号,与题目描述一致。 2. **重边处理**:读入边时使用 `g[a][b] = min(g[a][b], c)`,确保保留最短的边。 3. **无穷大值**:`0x3f3f3f3f` 是一个约定的极大值(约10^9),用于表示不可达。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值