杂选题目
归并排序
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;
}

浙公网安备 33010602011771号