zoukankan      html  css  js  c++  java
  • 算法准备-分治算法解决第k位数的线性查找

    由作业士兵排队问题引出的

    在一个划分成网格的操场上,n个士兵散乱地站在网格点上。网格点由整数最表(x,y)表示。士兵可以沿着网格边上、下、左、右移动一步,但在同一时刻一个网格上只能有一名士兵。按照军官的命令,士兵们要整齐地列成一个水平队列,即排列成(x,y),(x+1,y),…,(x+n-1,y)。如何选择x,y的值,才能使士兵们以最少的总移动步数排成一列。
    请计算使所有士兵排成一行需要的最少移动步数。

    这是一个课后题,通过推算可以得知该问题可以转化为一个求解中位数的问题。

    但在这里先不进行整个问题的求解,因为他的关键也是在于分治算法求解中位数

    中位数的求法一般来说是这样的:

    通过使用各种排序手段,然后得到最中间脚标对应的数,即是中位数。

    但其实并没有必要进行排序,因为我们只要求第k大的数,参考快速排序第一部分的分解,可以进行一下求解:

    代码如下:

    #include <bits/stdc++.h>
    
    using namespace std;
    int N;
    const int maxn = 1000;
    //int a[maxn];
    int b[maxn];
    
    int partitions(int *a, int l, int h)
    {
        //record the lwest part of array a
        int tmp = a[l];
    
        while(l < h)
        {
            //hgh first
            while(h > l && a[h] >= tmp){
                h--;
            }
            a[l] = a[h];
            while(l < h && a[l] <= tmp){
                l++;
            }
            a[h] = a[l];
        }
        a[l] = tmp;
        return l;
    }
    
    int findM1(int a[], int k, int l, int h) {
        int j = partitions(a, l, h);
    
        if (j == k) {
            return a[k];
        } else if (j > k) {
            return findM1(a, k, l, j - 1);
        } else {
            return findM1(a, k, j + 1, h);
        }
    }
    
    int findM2(int a[], int k , int n)
    {
        int l = 0;
        int h = n-1;
        while(l < h)
        {
            int j = partitions(a,l,h);
            if(j == k)
            {
                return a[k];
            }
            else if(j < k)
            {
                h = j-1;
            }
            else
            {
                l = j+1;
            }
        }
        return a[k];
    }
    
    
    int main()
    {
        int a[10] = {2,1,3,4,7,9,8,10,5,11};
    
        cout << findM1(a,3,0,9) << endl;
        cout << findM2(a,3,10) << endl;
    
        return 0;
    }
    
    

    有一些细节需要注意,可以查一下士兵排队问题,然后通过以上算法进行求解。

  • 相关阅读:
    猜数字游戏(补)
    团队项目五(项目回顾)
    项目回顾
    第二次阶段冲刺
    团队项目(任务三):第一次冲刺
    个人项目(一):新猜数字
    课后作业(一)
    团队任务二
    团队任务(一)
    课后作业(一)
  • 原文地址:https://www.cnblogs.com/pprp/p/9686212.html
Copyright © 2011-2022 走看看