蓝桥杯历届-移动距离

蓝桥杯历届-移动距离


移动距离

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范围内
w为排号宽度,m,n为待计算的楼号。
要求输出一个整数,表示m n 两楼间最短移动距离。

例如:
用户输入:
6 8 2
则,程序应该输出:
4

再例如:
用户输入:
4 7 20
则,程序应该输出:
5


#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int MAX = 10001;
int w, m, n, a[10001][10001];
void init() {
    int k = 0;
    for (int i = 0; i < MAX; i++) {
        k += w;
        for (int j = 0; j < w; j++) {
            if ((i+1) % 2 == 1) {
                a[i][j] = k-w+j+1;
            } else if((i+1) % 2 == 0){
                a[i][j] = k-j;
            }
        }
    }
    return; 
}
int getX(int num) {
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < w; j++) {
            if (a[i][j] == num) {
                return i;
            }
        }
    }
}
int getY(int num) {
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < w; j++) {
            if (a[i][j] == num) {
                return j;
            }
        }
    }
}
int main() {
    //freopen("in.txt", "r", stdin);
    scanf("%d%d%d", &w, &m, &n);
    init();
    int x1, x2, y1, y2;
    x1 = getX(m);
    x2 = getX(n);
    y1 = getY(m);
    y2 = getY(n);
    int sum = fabs(x1 - x2) + fabs(y2 - y1);
    cout << fabs(sum) << endl;
    return 0;
}

刚刚开始我用了dfs 原来那么简单 我也是醉了 坐标之差就行了


<think>好的,用户想了解蓝桥杯比赛中与“兔子集结”相关的算法题解。首先,我需要回忆一下蓝桥杯历年的真题,是否有类似“兔子集结”的题目。可能这个题目是某个具体问题的别称,或者是某个经典算法的变形。 先搜索一下记忆中的蓝桥杯题目,比如历届试题中的“蚂蚁感冒”、“分糖果”等,但不确定是否有直接叫“兔子集结”的。可能用户提到的题目是某个年份的真题,比如2015年或2018年的某个问题。或者可能题目中的“兔子”是比喻,实际涉及的是动态规划、贪心算法或者数学建模的问题。 接下来考虑可能的算法方向。题目提到集结,可能涉及到最优集合点的问题,比如所有兔子移动到某个点,使得总距离最小,类似中位数位置或者平均数的问题。或者可能涉及图论中的最短路径、BFS,比如兔子需要聚集到某个位置,计算最短步骤。 另外,可能题目中的集结需要考虑时间或资源消耗,比如每只兔子移动需要时间,求最短时间。这时候可能需要用到贪心算法或二分查找来确定最优解。例如,通过二分查找确定最小时间,然后验证每个时间是否可行。 假设题目是类似这样的:在数轴上有多个兔子的位置,找到一个点,使得所有兔子移动到该点的总距离最小。这种情况下,最优解就是所有坐标的中位数,此时总距离最小。这属于数学问题中的最优选址问题。 或者题目可能更复杂,比如兔子在移动过程中可能产生其他消耗,或者需要分组集结,这时候可能需要动态规划来处理。例如,将兔子分成若干组,每组移动到不同点,求最小总成本。 另外,考虑到蓝桥杯常考的算法包括贪心、动态规划、搜索等,可能需要结合这些算法来分析。例如,使用贪心策略选择中间点,或者用动态规划来分段处理。 还需要考虑输入输出的格式,比如输入是多个兔子的位置,输出是最小总移动距离或时间。如果是这样的话,计算每个点到中位数的距离之和即可。 假设题目是求最小总移动距离,那么算法步骤如下: 1. 输入兔子的位置数组。 2. 将数组排序。 3. 找到中位数位置。 4. 计算所有位置到中位数的距离之和。 例如,输入位置为[1,3,5],中位数是3,总距离为2 + 0 + 2 =4。 如果题目是求集结的最短时间,并且每只兔子可以同时移动,每移动一个单位距离需要1单位时间,那么最短时间就是最大距离的一半(如果向中间靠拢),或者最大距离到中位数的距离。例如,最远的两端到中间点的最大单程距离。 这时候可能需要找到中间点,然后计算最远点到中间点的距离作为时间。 此外,还需要考虑数据规模,如果数据量很大,可能需要更高效的算法,比如直接取中位数而不需要完全排序,可以用快速选择算法找到中间值。 总结可能的解题步骤: 1. 确定题目具体要求的是总距离还是最短时间。 2. 分析输入数据的特点,比如是否有序,数据范围。 3. 应用相应的算法,如排序求中位数,或二分查找确定时间。 另外,如果是二维平面上的集结问题,可能需要分别处理x和y坐标的中位数,但蓝桥杯题目通常简化为一维的情况。 可能的代码实现,例如排序后计算总距离: n = int(input()) positions = list(map(int, input().split())) positions.sort() median = positions[n // 2] total = sum(abs(pos - median) for pos in positions) print(total) 这应该是最小总距离的解法。 如果题目涉及其他约束,比如移动速度不同,或者集结点的数量不止一个,那么可能需要不同的方法,比如动态规划划分组别。 但根据用户提到的“兔子集结”,可能还是基于中位数的解法。需要确认题目的具体要求,但假设是经典的最小总移动距离问题,那么上述解答是合适的。</think>### 蓝桥杯“兔子集结”问题解析 在蓝桥杯竞赛中,“兔子集结”类问题通常涉及**数学建模**和**贪心算法**,核心目标是找到最优集合点使得总移动成本最小。以下以典型的一维数轴集结问题为例说明解法: --- #### 问题描述 $n$ 只兔子位于数轴的不同位置 $x_1, x_2, ..., x_n$,需选定一个点 $p$,使得所有兔子移动到 $p$ 的总距离最小。求最小总距离--- #### 算法思路 1. **排序定位**:将兔子的坐标排序后,**中位数**是最优集合点[^1]。 2. **计算总距离**:遍历所有坐标,累加每个位置到中位数的绝对距离--- #### 代码实现 ```python n = int(input()) positions = list(map(int, input().split())) positions.sort() median = positions[n // 2] # 取中位数 total_distance = sum(abs(x - median) for x in positions) print(total_distance) ``` --- #### 复杂度分析 - **时间复杂度**:$O(n \log n)$,主要来自排序操作。 - **空间复杂度**:$O(n)$,存储坐标数组。 --- #### 关键点 - **数学性质**:中位数可使绝对距离和最小(与平均数区分,平均数最小化平方距离和)。 - **扩展场景**:若要求**最短完成时间**(所有兔子同时移动),则计算最远兔子到中位数的单程距离--- 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值