杂选题目

归并排序

https://www.acwing.com/problem/content/789/

思想:

归并排序是把数组分成几个小的区间,进行排序,使之局部有序,之后两两合并,形成更大的局部有序,最后使之全局有序

所以总体来看,就是递归的思想,递归的方法:

void merge_sort(int l, int r, int* q)
{
	if(l >= r)return;//退出
    int mid = l + r >> 1;
    merge_sort(l, mid);
    merge_sort(mid + 1, r);//分割
    //(l,mid)已经有序,(mid + 1, r)有序
    //接下来给(l,r)排序
    int i = l, j = mid + 1, res[r - l + 1], k = 0;
    while(i <= mid && j <= r)
        res[k ++] = q[j] >= q[i] ? q[i ++] :q[j ++];
    while(i <= mid)
        res[k ++] = q[i ++];
    while(j <= r)
        res[k ++] = q[j ++];
    //将结果寄存在res中
    for(int n = 0; n < k; n ++)
        q[n + l] = res[n];
    //给q赋值
}

以上就是核心代码,下面给出全部代码:

#include<iostream>

using namespace std;

int a[100010];

void merge_sort(int l, int r)
{
    int mid = l + r >> 1;
	if(l >= r)return;//退出
    merge_sort(l, mid);
    merge_sort(mid + 1, r);//分割
    //(l,mid)已经有序,(mid + 1, r)有序
    //接下来给(l,r)排序
    int i = l, j = mid + 1, res[r - l + 1], k = 0;
    while(i <= mid && j <= r)
        res[k ++] = a[j] >= a[i] ? a[i ++] : a[j ++];
    while(i <= mid)
        res[k ++] = a[i ++];
    while(j <= r)
        res[k ++] = a[j ++];
    //将结果寄存在res中
    for(int n = 0; n < k; n ++)
        a[n + l] = res[n];
    //给q赋值
}

int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i ++)
        cin >> a[i];
    merge_sort(0, n - 1);
    for(int i = 0; i < n; i ++)
        cout << a[i] << " ";
    return 0;
}

该算法的时间复杂度是O(nlog(n))级别的

算是枚举集合

移动距离

https://www.acwing.com/problem/content/1221/

分析

这个题唯一的难点就是给出两个数和每排的楼数,怎样去计算楼的位置,正向的和反向的都有一点问题

行号好说,m / w + 1,但是有一个坑,就是楼号正好是w的倍数,这时候加一就不行了,所以得判读一下

麻烦的是列号,奇数排(排数从1开始编号)是正向,偶数排是反向,正向的时候就得是取余,但是有一个问题,由于题目,我们从一开始,所以每次遇到w的倍数就无法安放因为题目中的例子:6号楼在6位置,12号楼在1位置,但是他们取余都是0,所以还得进一步考虑。

先看奇数行,假如n号楼在m位置,对 w + 1取余,当m在第一行时是可行的,但是在3, 5 ……就不准确了,所以得考虑前面的行数,假如m楼在第i行,那么前i - 1行已经占满,所以m - (i - 1)* w就是其所在位置

再看偶数行,位置同上,因为是反向的,其位置应当是w - m - (i - 1)* w + 1

计算出两楼位置之后就能得到所需的结果。

#include<iostream>

using namespace std;

int main()
{
    int w, m, n;
    int dirm, dirn;
    cin >> w >> m >> n;
    dirm = m / w + ((m % w) == 0 ? 0 : 1), dirn = n / w + ((n % w) == 0 ? 0 : 1);
    pair<int, int> pos_m, pos_n;
    pos_m.first = dirm, pos_n.first = dirn;
    if(dirm & 1)pos_m.second = (m - (dirm - 1) * w) % (w + 1) % (w + 1);
    else pos_m.second = w - ((m - (dirm - 1) * w) % (w + 1)) + 1;
    if(dirn & 1)pos_n.second = (n - (dirn - 1) * w) % (w + 1) % (w + 1);
    else pos_n.second = w - ((n - (dirn - 1) * w) % (w + 1)) + 1;
    cout << abs(pos_m.first - pos_n.first) + abs(pos_m.second - pos_n.second);
    return 0;
}
posted @ 2021-03-01 00:47  kanbujian55  阅读(57)  评论(0)    收藏  举报