# acm/icpc live archive 2481, world final 2002 problem h. silly sort

Your younger brother has an assignment and needs some help. His teacher gave him a sequence of numbers to be sorted in ascending order. During the sorting process, the places of two numbers can be interchanged. Each interchange has a cost, which is the sum of the two numbers involved.

You must write a program that determines the minimal cost to sort the sequence of numbers.

## Input

The input file contains several test cases. Each test case consists of two lines. The first line contains a single integer n (n >1), representing the number of items to be sorted. The second line contains n different integers (each positive and less than 1000), which are the numbers to be sorted.

The input is terminated by a zero on a line by itself.

## Output

For each test case, the output is a single line containing the test case number and the minimal cost of sorting the numbers in the test case.

Place a blank line after the output of each test case.

## Sample Input

3
3 2 1
4
8 1 2 4
5
1 8 9 7 6
6
8 4 5 3 2 7
0


## Sample Output

Case 1: 4

Case 2: 17

Case 3: 41

Case 4: 34


1。引入全局最小值到群里，用最小值每次置换恢复一个数字的位置；
2。不引入全局最小值，用群里最小值，每次置换恢复一个数字的位置。

#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <algorithm>

#define SZ_MAX 100000

int num [SZ_MAX];
int sorted [SZ_MAX];
int sz;
int globMin;

#define NUM_MAX 1010

void Sort () {
static int cnt [1010];
memset (cnt, 0, sizeof (cnt));
for (int i=0; i<sz; ++i) {
++cnt [num [i]];
}
int ind = 0;
for (int i=0; i<NUM_MAX; ++i) {
while (cnt[i]--) {
sorted [ind++] = i;
}
}
assert (ind == sz);
#ifdef _DEBUG
for (int i=0; i<sz; ++i) {
printf ("%d%s", sorted[i], i==sz-1 ? "\n" : " ");
}
#endif
}

int BinSearch (int n) {
int lo = 0;
int hi = sz - 1;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (sorted [mid] < n) {
lo = mid + 1;
} else {
hi = mid;
}
}
assert (sorted [lo] >= n);
assert (lo == 0 || sorted [lo - 1] < n);
return lo;
}

void Solve () {
if (scanf ("%d", &sz) == EOF || !sz) {
exit (0);
}
globMin = 100000;
for (int i=0; i<sz; ++i) {
scanf ("%d", &num[i]);
globMin = std::min (globMin, num [i]);
}
Sort ();

static bool marked [SZ_MAX];
memset (marked, 0, sizeof (marked));

int cost = 0;

for (int i=0; i<sz; ++i) {
if (marked [i] || sorted [i] == num [i]) {
continue;
}
int k = i;
int sum = 0;
int troopMin = 100000;
int troopSz = 0;
do {
#ifdef _DEBUG
printf ("i = %d, k = %d\n", i, k);
#endif
troopMin = std::min (troopMin, sorted [k]);
sum += sorted [k];
assert (! marked [k]);
marked [k] = true;
++troopSz;
k = BinSearch (num [k]);
while (k < sz && (sorted [k] == num [k] || marked [k]) && i != k) {
++k;
}
assert (k < sz);
} while (k != i);

cost += sum + std::min ((troopSz + 1) * globMin + troopMin, (troopSz - 2) * troopMin);
#ifdef _DEBUG
printf ("cost = %d\n", cost);
#endif
}

static int cs = 0;
printf ("Case %d: %d\n\n", ++cs, cost);
}

int main () {
while (true) {
Solve ();
}
return 0;
}


• 本文已收录于以下专栏：

举报原因： 您举报文章：acm/icpc live archive 2481, world final 2002 problem h. silly sort 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)