昨日刷的题目较为简单,没有需要做笔记记录的,所以没有进行记录。今日的题目也很简单,都是暴力能过,不过记录一下之后数据量大的做法。
求逆序数最常规的做法就是一个个遍历,其次就是根据归并排序的思想求取。这里记录一下使用归并排序的做法。
class Solution {
public:
int mod = 1000000007;
int mergeSort(int left, int right, vector<int>& data, vector<int>& temp){
// 停止划分 fast-template
if (left >= right)
return 0;
//取中间
int mid = (left + right) / 2;
//左右划分
int res = mergeSort(left, mid, data, temp) + mergeSort(mid + 1, right, data, temp);
//防止溢出
res %= mod;
int i = left, j = mid + 1;
for (int k = left; k <= right; k++)
temp[k] = data[k];
for (int k = left; k <= right; k++) {
if (i == mid + 1)
data[k] = temp[j++];
else if (j == right + 1 || temp[i] <= temp[j])
data[k] = temp[i++];
//左边比右边大,答案增加
else {
data[k] = temp[j++];
// 统计逆序对
res += mid - i + 1;
}
}
return res % mod;
}
int InversePairs(vector<int> data) {
int n = data.size();
vector<int> res(n);
return mergeSort(0, n - 1, data, res);}
};
可以在纸上模拟一下,当两个蚂蚁碰撞后,两个蚂蚁调转方向,但是可以看作是两个蚂蚁没有调转方向,而是进行了一次互换,这样只需要记录所有蚂蚁的位置,然后求取一个离两端出口都距离最远的一个蚂蚁距离即可。
#include <bits/stdc++.h>
using namespace std;
int main() {
int m, n;//m:蚂蚁数量 n:小径长度
int lf, x;//lf:向左或向右 x:初始坐标
cin >> m >> n;
vector<int> p;
for(int i = 1; i <= n; i++) {
cin >> lf >> x;
if(lf == 1)
p.emplace_back(m - x);
else if(lf == 0)
p.emplace_back(x);
}
sort(p.begin(), p.end());
cout << p[n - 1];
return 0;
}