11571: 【原1571】最小花费
题目
题目描述
author: lwher 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1571 # Description 土豪李老板买了两包砖石,每包砖石各有N颗,每个砖石各有一个价值。现在李老板将每包砖石都排成一排,且同一排砖石的价值互不相同。
有一天李老板和人赌钱,他们认为这两包砖石的价值差距可以定义为sigma(Ai - Bi)^2
,其中Ai,Bi
分别表示第一、第二包砖石排在第i
位的砖石,他们根据随机排列的两包砖石价值差距的大小来判断输赢。
李老板经过思考,他打算买小,但他又觉得不稳健,于是他打算贿赂排砖石的人。排砖石的人每次可以交换相邻两颗砖石,李老板希望那个人通过若干次交换使得砖石价值差距最小,现在问最少要交换几次。
如果答案太大,请输出这个答案对99,999,997取模的结果。
李老板:这题如果不会做,也可以随时来找我。
Input Format
第一行有一个整数N
,代表每包砖石的个数。
第二行 N
个数代表李老板买的第一包砖石的价值{X_1,X_2,…,X_N}
。
第三行 N
个数代表李老板买的第二包砖石的价值{Y_1,Y_2,…,Y_N}
。
Output Format
一个整数,即李老板想要的答案。
Sample Input
4
2 3 1 4
3 2 1 4
Sample Output
1
Sample Input
4
1 3 4 2
1 7 2 4
Sample Output
2
样例1说明
最小距离是 0,最少需要交换 1 次,比如:交换第 1 列的前 2 根火柴或者交换第 2 列的前 2 根火柴。
样例2说明
最小距离是 10,最少需要交换 2 次,比如:交换第 1 列的中间 2 根火柴的位置,再交换第 2 列中后 2 根火柴的位置。
Limits
- 对于\(10\%\)的数据,1<= N <= 10。
- 对于\(30\%\)的数据,1<= N <= 100。
- 对于\(60\%\)的数据,1<= N <= 1000。
- 对于\(100\%\)的数据,1 <= N <= 100000, 0 <= 砖石价值 <= 2^31-1。
ligongzzz's solution
#include "iostream"
#include "cstdio"
#include "cmath"
using namespace std;
long long myMergeSort(int *data, int num) {
if (num == 0) return 0;
else if (num == 1) return 0;
long long result = 0;
result += myMergeSort(data, num / 2);
result += myMergeSort(data + num / 2, num - num / 2);
//合并
int *temp = new int[num];
for (int i = 0, j = num / 2, n = 0; i < num / 2 || j < num;n++) {
if (i < num / 2 && j < num) {
if (data[i] < data[j]) {
temp[n] = data[i];
i++;
result += j-num/2;
}
else {
temp[n] = data[j];
j++;
}
}
else if (i == num / 2) {
temp[n] = data[j];
j++;
}
else if (j == num ) {
temp[n] = data[i];
i++;
result += j-num/2;
}
}
//复制
for (int i = 0; i < num; i++)
data[i] = temp[i];
delete temp;
return result;
}
long long myMergeSort(int *data,int *datab,int num) {
if (num == 0) return 0;
else if (num == 1) return 0;
long long result = 0;
result += myMergeSort(data,datab, num / 2);
result += myMergeSort(data + num / 2,datab+num/2, num - num / 2);
//合并
int *temp = new int[num];
int *tempb = new int[num];
for (int i = 0, j = num / 2, n = 0; i < num / 2 || j < num; n++) {
if (i < num / 2 && j < num) {
if (data[i] < data[j]) {
temp[n] = data[i];
tempb[n] = datab[i];
i++;
result += j - num / 2;
}
else {
temp[n] = data[j];
tempb[n] = datab[j];
j++;
}
}
else if (i == num / 2) {
temp[n] = data[j];
tempb[n] = datab[j];
j++;
}
else if (j == num) {
temp[n] = data[i];
tempb[n] = datab[i];
i++;
result += j - num / 2;
}
}
//复制
for (int i = 0; i < num; i++) {
data[i] = temp[i];
datab[i] = tempb[i];
}
delete temp;
delete tempb;
return result;
}
int a[100009], b[100009],aList[100009],bList[100009],temp[100009];
int main() {
int num;
cin >> num;
for (int i = 0; i < num; i++) {
scanf("%d", &a[i]);
aList[i] = i;
}
for (int i = 0; i < num; i++) {
scanf("%d", &b[i]);
bList[i] = i;
}
//排序
myMergeSort(a, aList, num);
myMergeSort(b, bList, num);
//按情况排序
for (int i = 0; i < num; i++) {
temp[bList[i]] = aList[i];
}
//再排序
cout << myMergeSort(temp, b, num)%99999997;
return 0;
}
Neight99's solution
#include <algorithm>
#include <iostream>
using namespace std;
struct Node {
int pos;
int data;
};
bool cmp(Node, Node);
int Low(int);
void plus1(int);
int sum1(int);
Node A[100010], B[100010];
int c[100010], d[100010], N, ans;
int main() {
cin >> N;
for (int i = 1; i < N + 1; i++) {
cin >> A[i].data;
A[i].pos = i;
}
for (int i = 1; i < N + 1; i++) {
cin >> B[i].data;
B[i].pos = i;
}
sort(A + 1, A + N + 1, cmp);
sort(B + 1, B + N + 1, cmp);
for (int i = 1; i < N + 1; i++) {
d[A[i].pos] = B[i].pos;
}
for (int i = N; i > 0; i--) {
plus1(d[i]);
ans = (ans + sum1(d[i] - 1)) % 99999997;
}
cout << ans % 99999997;
return 0;
}
bool cmp(Node x, Node y) { return x.data < y.data; }
int Low(int x) { return x & (-x); }
void plus1(int x) {
for (int i = x; i < N + 1; i += Low(i)) {
c[i]++;
}
return;
}
int sum1(int x) {
int sum = 0;
for (int i = x; i != 0; i -= Low(i)) {
sum = (sum + c[i]) % 99999997;
}
return sum % 99999997;
}
/*void sort(Node *N,int a,int b) {
if(a>b) {
return;
} else {
int first = a, last = b;
Node n = N[first];
while (first < last) {
while (first < last && !cmp(N[last], n)) {
last--;
}
N[first] = N[last];
while (first < last && cmp(N[last], n)) {
first++;
}
N[last] = N[first];
}
N[first] = n;
sort(N, a, first - 1);
sort(N, first + 1, b);
}
for(int i=a;i<b-1;i++) {
for(int j=a;j<b-i-1;j++) {
Node tmp;
if(cmp(N[j],N[j+1])!=0) {
tmp=N[j];
N[j]=N[j+1];
N[j+1]=tmp;
}
}
}
}*/