2019年蓝桥杯练习3-楼号m和n之间的最短移动距离

本文详细解析了2019年蓝桥杯竞赛中一道关于寻找两座建筑间最短移动距离的题目。通过分析建筑编号的排列规律,提出了一种基于行列坐标的算法,用于计算任意两座建筑间的最短距离。该算法适用于X星球居民小区这种特定布局,且考虑了不能斜线移动的限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2019年蓝桥杯练习3-楼号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

分析:

/*
找规律知:最短移动距离为两点横坐标差的绝对值+纵坐标差的绝对值。
奇数行:从小到大
偶数行:从大到小 
*/

#include<stdio.h>
#include<math.h>
int row(int w,int i) { //计算点的行号 
	int irow;  //下列计算取第一行的行号为1,而不是0 
	if(i%w==0) //值是宽度的倍数 
		irow=i/w;
	else      //值不是宽度的倍数 
		irow=i/w+1;
	return irow;
}
int col(int w,int j) {  //计算点的列号 
	int jcol;    //下列计算取第一列的列号为1,而不是0 
	if(row(w,j)%2==0) {  //该值在偶数行 
		if(j%w==0)  // 找规律可知,偶数行能被整除肯定在第一列 
		    jcol=1;
        else      //在偶数行(从大到小)但不能被整除,在倒数第j%w列,即正数第w-j%w+1列 
		    jcol=w-j%w+1;
	} else {  //在奇数行 
    	if(j%w==0)   //找规律可知,偶数行能被整除肯定在最后一列 
            jcol=w;
        else     //在奇数行(从小到大)但不能被整除,在第j%w列 
            jcol=j%w;
	}
	return jcol;
}
int main()
{
	int w,m,n;
	while(scanf("%d %d %d",&w,&m,&n)==3) {
		int s=fabs(row(w,n)-row(w,m))+fabs(col(w,n)-col(w,m));
		printf("%d\n",s);
	}
 	return 0;	
}

分析: 

 可以不用想得太复杂,直接找规律,重点是找到计算行号和列号的规律,多验证几组边缘的数据来确定规律是否正确。

<think>好的,我现在要解决用户关于第六届蓝桥杯移动距离”的问题。首先,我需要回忆这个题目的具体内容。根据题目描述,移动距离问题通常涉及在某种排列的矩阵中,计算两个点之间的曼哈顿距离。例如,数字按照蛇形排列,比如第一行从左到右,第二行从右到左,依此类推,形成一个蛇形矩阵。用户需要找到两个数字mn在这样的矩阵中的坐标,并计算它们的曼哈顿距离。 首先,我需要明确题目的具体要求。通常这类题目会给出楼号的排列方式,比如每行有w个数字,奇数行正序排列,偶数行逆序排列。然后给定两个楼号mn,要求计算它们之间移动距离,也就是曼哈顿距离。曼哈顿距离的计算公式是|x1 - x2| + |y1 - y2|。因此,关键在于如何正确确定两个楼号所在的行列。 接下来,我需要考虑如何将楼号转换为对应的行列。行号可以通过楼号除以每行的数字数量w来得到,但要注意向上取整。例如,楼号m所在的行是(m-1)//w,因为索引可能从0或1开始,这里可能需要根据题目具体调整。例如,如果行号从1开始,那么行号应该是(m-1)//w +1?或者要看题目是否从0或1开始计数。需要仔细看题目描述。 假设题目中的行号从0开始,或者从1开始?比如,假设每行有w个数字,那么对于某个数字k,行号是 (k-1) // w,这样行号从0开始。或者如果题目中的行号从1开始,那么行号就是 (k-1) // w +1。例如,当w=3时,数字1-3在第一行(行号0或1?),4-6在第二行,以此类推。这点需要明确,否则坐标计算会出错。 其次,列号的确定。对于奇数行(假设行号从1开始),数字从左到右排列,那么列号为 (k-1) % w。如果是偶数行,则逆序排列,列号应为 w - 1 - (k-1)%w。例如,行号为奇数时,比如第一行,列号0到w-1;第二行则为逆序,所以数字在该行的位置需要从右到左排列。或者,如果行号从0开始,那么奇数行偶数行的判断可能需要调整,例如行号为偶数(0,2,4...)时是正序,奇数行时是逆序?这需要根据题目具体示例来判断。 例如,假设每行w=3,那么排列可能如下: 行1(奇数):1 2 3 → 行号0或者1? 行2(偶数):6 5 4 → 行号1或者2? 这个时候,假设行号从1开始,那么行号为奇数的行正序,偶数的行逆序。例如,行号是i+1,其中i是计算得到的行索引。或者可能行号直接是i+1,所以当i是0(第一行)时为奇数,正序;i=1(第二行)时为偶数,逆序。 这个时候,正确的坐标计算方法应该是: 对于楼号k: 行号:row = (k-1) // w 列号:col_in_row = (k-1) % w 如果行号row是偶数(假设行号从0开始),则正序,列号为col_in_row; 如果行号row是奇数,则逆序,列号为 w - 1 - col_in_row。 或者,如果题目中的行号从1开始,那么判断行号的奇偶性,如果是奇数行,列正序,否则逆序。例如: row = (k-1) // w + 1 → 行号从1开始。 如果 row是奇数,那么列号为 (k-1)%w; 否则,列号为 w-1 - (k-1)%w。 这一步是关键,如果行号列号计算错误,坐标就会错,曼哈顿距离也会错误。所以必须根据题目中的具体排列规则来确定。 接下来,我需要查看用户提供的引用内容,但用户给出的引用可能并不直接相关。例如,引用[1]是关于全排列的,引用[2]提到九数组分数,引用[3]是关于路径规划。这些可能移动距离问题无关。不过用户可能希望得到示例代码,因此需要根据常规的移动距离问题来解答。 假设题目中的排列规则是行号从1开始,每行w个数字,奇数行正序,偶数行逆序。例如,当w=3时,排列如下: 行1:1 2 3 行2:6 5 4 行3:7 8 9 行4:12 11 10 对于某个数字k,行号是 (k-1)//w +1。例如,k=6 → (6-1)/3=1.666,整数部分是1 → 行号2?或者行号是1?或者这里的行号是否从0开始? 可能需要通过例子来验证。比如,当w=3,k=4在第2行,行号为2?或者行号为1? 比如,当k=4时,(4-1)//3 =1 → 行号是1(如果从0开始)或者2(如果从1开始)。例如,假设行号从0开始: 行0:1-3 行1:6-4(逆序) 行2:7-9 行3:12-10(逆序) 这时,行号为i,当i为奇数时,该行逆序。这可能更符合常规的编程处理,因为索引从0开始。 所以,正确的坐标计算可能是: 行号:row = (k-1) // w 列号:col_in_row = (k-1) % w 如果 row是奇数,则列号为 w - 1 - col_in_row; 否则,保持原样。 例如,k=6时,row=(6-1)//3=5//3=1 → 奇数行,所以列号=3-1 - (5%3)=2 - 2=0?或者原式是w-1 - (k-1)%w → 3-1 - (6-1)%3=2 - 1=1? 这里可能要看具体例子。比如,当w=3,行1是逆序排列,k=4在行1的位置是0,k=5在行1的位置1,k=6在行1的位置2?或者反过来? 假设行号为row,从0开始: 行0:1,2,3 → 列0,1,2 行1:6,5,4 → 列0→6,1→5,2→4? 或者行1的数字是6,5,4,那么它们的列号是0,1,2,但数字是按照逆序排列的。即,数字4的位置是列2?因为该行从右到左填充。例如,行号为奇数时,数字的排列顺序是逆序的,所以该行中的第一个数字是该行大的数,后一个数字是该行小的数。例如,行1中的数字是6,5,4,对应的列号为0,1,2,但它们的排列顺序是6在列0,5列1,4列2?或者原问题中可能行号为偶数时逆序? 这可能需要具体题目示例来判断。比如,题目可能给出一个例子,比如w=3,m=6n=2的距离是多少。或者需要根据题目中的例子来推导。 例如,假设题目中的示例输入为:w=3,m=6,n=2,那么对应的坐标可能为: 对于m=6: 行号=(6-1)/3=5/3=1 → row=1(从0开始) 因为row是奇数,所以列号是3-1 - (6-1)%3=2 - 2=0 → 所以坐标是(1,0)? 对于n=2: 行号=(2-1)/3=0 → row=0,偶数行,列号=(2-1)%3=1 → 坐标(0,1) 曼哈顿距离是 |1-0| + |0-1|=1+1=2?或者行号是否作为x坐标,列号作为y坐标? 或者,可能行号作为x坐标,列号作为y坐标。例如,两个点的坐标分别为(row_m, col_m)(row_n, col_n),所以曼哈顿距离是 |row_m - row_n| + |col_m - col_n|。 这时候,假设输入w=3,m=6,n=2,得到的距离是 |1-0| + |0-1|=1+1=2。这可能是一个可能的例子。 因此,正确的逻辑应该是: 1. 计算每个数字的行号:row = (k-1) // w 2. 计算所在行的原始列号:col = (k-1) % w 3. 如果行号是奇数,则列号调整为 w-1 - col 4. 否则,列号保持不变 然后计算两个坐标的曼哈顿距离。 现在,我需要编写相应的代码。例如,用Python实现: def get_coordinate(k, w): row = (k - 1) // w col = (k - 1) % w if row % 2 == 1: # 或者判断是否为奇数行,注意是否从0开始 col = w - 1 - col return (row, col) m = 6 n = 2 w =3 x1, y1 = get_coordinate(m, w) x2, y2 = get_coordinate(n, w) distance = abs(x1 -x2) + abs(y1 - y2) print(distance) 假设这样得到的距离是2,如之前的例子。 接下来,需要处理可能出现的行号判断是否正确。例如,行号从0开始,当row为奇数(比如1,3,5等)时,该行是逆序排列。因此,在代码中判断row %2 ==1是正确的。 但是,是否题目中的行号从1开始?例如,在题目中,行号可能按1、2、3...编号,此时,奇数行需要逆序。这时候,row的值为(k-1)//w,得到的是从0开始的行号,所以行号+1才是实际行号。此时,判断实际行号是否为奇数: 比如,实际行号是 row+1,所以如果 (row+1) %2 ==1 → row是偶数。因此,代码可能需要调整。例如: 实际行号 = row +1 if (actual_row) %2 ==0 → 即当实际行号是偶数时,该行逆序。 这时候,代码的判断条件可能需要改变。例如: actual_row = (k-1) // w +1 if actual_row %2 ==0: col = w-1 - col 或者,如果题目中的行号是从1开始的,并且奇数行正序,偶数行逆序,那么: row = (k-1) //w actual_row = row +1 if actual_row %2 ==0: col = w-1 - col 这将影响坐标的计算。比如,当w=3,k=4时: row=(4-1)//3=1 → actual_row=2 → 偶数 → col=3-1 - (4-1)%3=2-0=2 → 列号为2。即,在第二行(实际行号2)中的位置是2,对应的数字是4? 这可能与之前的例子冲突。比如,当实际行号为2时,数字排列是逆序的,即该行的三个数字是6、5、4。所以,k=4的位置应该是该行的第三个数字,即列号2。所以在这种情况下,get_coordinate(4,3)应返回row=1(原行号),实际行号2,偶数,所以列号调整。原col是 (4-1)%3=0 → 调整后的col是 2 → 所以坐标是(1,2),对应数字4的位置。是的,这样是正确的。 所以,这样的代码是正确的。例如,当k=6时,row=(6-1)//3=1 → actual_row=2,偶数行,所以col= (6-1)%3=2 → 调整后的col= 3-1 -2=0?或者原式是w-1 - (k-1)%w → 3-1 -2=0 → col=0。对应的数字是6的位置(在行2,逆序排列)。是的,此时6在列0的位置。 所以,正确的判断条件应该基于实际行号是否为偶数。因此,在代码中,row的计算是 (k-1)//w,然后实际行号是 row+1。如果实际行号是偶数,则逆序排列。此时,判断条件应为: if (row +1) %2 ==0 → 即实际行号为偶数时,调整列号。 因此,在代码中: def get_coordinate(k, w): row = (k -1) //w actual_row = row +1 col = (k-1) %w if actual_row %2 ==0: col = w-1 - col return (row, col) 或者,更简洁的方式,不计算actual_row,而是通过row的奇偶性。例如,当实际行号是 row+1,当row+1是偶数 → row是奇数。因此,当row是奇数时,需要调整列号。即: if (row %2) ==1: # 因为 row+1是偶数 → row是奇数 col = w-1 - col 这样,可以简化代码: def get_coordinate(k, w): row = (k-1) //w col = (k-1) %w if row %2 ==1: col = w-1 - col return (row, col) 这似乎更简单。例如,当row是1时(对应实际行号2),调整列号。比如,k=4时,row=1,col=0 → 调整后的col=2,正确。 所以,这样的代码是正确的。这取决于题目中的行号是否从1开始,并且当实际行号为偶数时逆序排列。通过这种方式,判断row的奇偶性即可,而无需计算actual_row。 综上所述,正确的坐标计算步骤为: 1. 计算行号row = (k-1) // w 2. 计算原始列号col = (k-1) %w 3. 如果row是奇数,则调整列号为w-1 -col 4. 返回rowcol作为坐标 然后,计算曼哈顿距离。 现在,针对用户的问题,需要给出第六届蓝桥杯移动距离问题的解析示例代码。根据上述分析,可以编写解析步骤代码。 此外,可能需要注意输入的参数,比如w是宽度,mn是要计算的两个楼号。例如,输入可能是w、m、n,然后输出它们的曼哈顿距离。 示例输入可能如: 输入: 6 8 2 (假设w=6,m=8,n=2) 需要计算它们的坐标。 例如,w=6,m=8: row = (8-1)//6 =7//6=1 → row=1,奇数 → 调整列号。原始列号是7%6=1 → 调整后的列号是6-1-1=4 → 所以坐标是(1,4) n=2: row=(2-1)//6=0 → row=0,偶数 → 列号是1%6=1 → 坐标是(0,1) 曼哈顿距离为 |1-0| + |4-1|=1+3=4. 因此,示例代码应正确输出结果。 综上,示例代码如下: w, m, n = map(int, input().split()) def get_coord(k): row = (k-1) // w col = (k-1) % w if row % 2 == 1: col = w - 1 - col return row, col x1, y1 = get_coord(m) x2, y2 = get_coord(n) distance = abs(x1 - x2) + abs(y1 - y2) print(distance) 需要注意的问题包括行数的计算是否正确,列号是否在逆序时正确处理。例如,当行号为奇数时调整列号。 因此,在解析中需要详细说明坐标的计算方法,并通过示例说明。</think>### 第六届蓝桥杯移动距离”问题解析 **问题描述** 在蛇形排列的矩阵中,数字按行填充,奇数行(从1开始计数)正序排列,偶数行逆序排列。给定每行宽度 $w$ 两个楼号 $m$、$n$,要求计算它们之间的曼哈顿距离。 **关键思路** 1. **坐标计算** - **行号**:楼号 $k$ 的行号为 $(k-1) // w$(从0开始计数)。 - **列号**:若行号为奇数,列号为逆序排列:$w-1 - (k-1)\%w$;否则保持正序:$(k-1)\%w$。 2. **曼哈顿距离**:$|x_1 - x_2| + |y_1 - y_2|$,其中 $(x_1, y_1)$ $(x_2, y_2)$ 是 $m$ $n$ 的坐标。 **示例代码** ```python w, m, n = map(int, input().split()) def get_coord(k): row = (k - 1) // w col = (k - 1) % w if row % 2 == 1: col = w - 1 - col return row, col x1, y1 = get_coord(m) x2, y2 = get_coord(n) distance = abs(x1 - x2) + abs(y1 - y2) print(distance) ``` **示例分析** 假设输入为 $w=3$,$m=6$,$n=2$: 1. $m=6$ 的坐标为 $(1, 0)$(行1为奇数,逆序)。 2. $n=2$ 的坐标为 $(0, 1)$(行0为偶数,正序)。 3. 曼哈顿距离为 $|1-0| + |0-1| = 2$。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值