-
3,1,2 1,2,3,4,5
样例输出
-
1 0
Description
Find a pair in an integer array that swapping them would maximally decrease the inversion count of the array. If such a pair exists, return the new inversion count; otherwise returns the original inversion count.
Definition of Inversion: Let (A[0], A[1] ... A[n], n <= 50) be a sequence of n numbers. If i < j and A[i] > A[j], then the pair (i, j) is called inversion of A.
Example:
Count(Inversion({3, 1, 2})) = Count({3, 1}, {3, 2}) = 2
InversionCountOfSwap({3, 1, 2})=>
{
InversionCount({1, 3, 2}) = 1 <-- swapping 1 with 3, decreases inversion count by 1
InversionCount({2, 1, 3}) = 1 <-- swapping 2 with 3, decreases inversion count by 1
InversionCount({3, 2, 1}) = 3 <-- swapping 1 with 2 , increases inversion count by 1
}
Input
Input consists of multiple cases, one case per line.Each case consists of a sequence of integers separated by comma.
Output
For each case, print exactly one line with the new inversion count or the original inversion count if it cannot be reduced.
思路,此题采用的是暴力法,不过改进的一个地方是计算InversionCount的算法,采用的是合并排序,时间复杂度是O(nlogn)
import java.util.Scanner;
public class Main {
static int InversionCount ;
public static void main(String[] args)
{
int T,t;
Scanner jin = new Scanner(System.in);
while (jin.hasNext()) {
String str = jin.next();
String[] argstr = str.split(",");
int[] num = new int[argstr.length];
int[] tmp = new int[argstr.length];
for (int i = 0; i < num.length; i++) {
num[i] = Integer.parseInt(argstr[i]);
tmp[i] = Integer.parseInt(argstr[i]);
}
InversionCount = 0;
MergeSort(tmp, 0, tmp.length-1);
int ret = InversionCount;
for (int i = 0; i < num.length; i++)
tmp[i] = num[i];
for (int i = 0; i < num.length-1; i++) {
for (int j = i+1; j < num.length; j++) {
if (num[i] > num[j]) {
int tmpnum = num[i];
num[i] = num[j];
num[j] = tmpnum;
InversionCount = 0;
MergeSort(num, 0, num.length-1);
ret = Math.min(ret, InversionCount);
for (int k = 0; k < num.length; k++)
num[k] = tmp[k];
}
}
}
System.out.println(ret);
}
}
public static void MergeSort(int[] array, int lhs, int rhs) {
if (lhs < rhs) {
int mid = lhs + ((rhs - lhs)>>1);
MergeSort(array, lhs, mid);
MergeSort(array, mid+1, rhs);
Merge(array, lhs, mid, rhs);
}
}
public static void Merge(int[] array, int lhs, int mid, int rhs) {
int[] tmp = new int[rhs-lhs+1];
int i = lhs, j = mid+1;
int k = 0;
while(i <= mid && j <= rhs)
{
if (array[i] > array[j]) {
InversionCount += mid-i+1;
tmp[k++] = array[j++];
}
else {
tmp[k++] = array[i++];
}
}
while(i <= mid)
{
tmp[k++] = array[i++];
}
while(j <= rhs)
{
tmp[k++] = array[j++];
}
for (i = 0; i < k; i++) {
array[i+lhs] = tmp[i];
}
tmp = null;
}
}