#89 C

Start from the baseline number, which ranges from 0 to 9, giving a baseline number B, and digit sequence N(i) 1<=i<=n, I generate another digit sequence D(i), whose elements are B - N(i).

Sorting D(i), then the first K digit can sum the minimun result of prize.

But when there is equal minimun prize, I still need some method to pick the lexicographic order smaller one.

One approach came to me is that for every baseline number, after sorting D(i), generate the third digit sequence whose elements are changed to baseline number.

Using this sequence to compare the lexicographic order.

Got wrong answer at test 05, because for a given baseline number, I didn't sort the diff correctly, the key is how to sort the digit when two digits have same diff.

Look at the index structure:

typedef struct index_st {
char diff;
char *p_digit;
} index_st;

p_digit is the origin digit pointer, this field can help to determin which digit is first (from left to right) , when comparing to digits.

I got it, suppose baseline number is 6, and to digits are 4 and 8.

if change 4, then I get 6, 8

if change 8, then I get 4, 6

4,6 < 6,8 in lexicographic order.

so, first determin which digit first, and then calculate the tuple by changing one digit to baseline number.

After wrong answer for about 10 times, I found that this conclusion is not perfect, but I don't know where dose it wrong.

But now I change the conclusion as:

1) if two digits has different abs(diff) value, then less abs(diff) value has higher priority.

2) if two digits has same abs(diff) value, but one of the diff value is postive, and another is negative, then the postive one has higher priority, because no matter what position relationship this

    two digit are, the algorithm tend to decrease value to baseline number instead of increase value.

3) if two digit has exactly same diff value, then , when the diff > 0, digit at left has higher priority, because the left digit would decrease value, on the other hand, when diff < 0, then should increase the right digit , not the left one.

finally Accepted.

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define MAX 10000

typedef struct index_st {
int diff;
int p_digit;
} index_st;

index_st indexs[10][MAX] = { 0 };
int gen_digits[10][MAX] = { 0 };
char in_digits[MAX] = { 0 };

int index_cmp(const void *i1, const void *i2) {
int d1 = ((index_st*)i1)->diff, d2 = ((index_st*)i2)->diff;
int d = abs(d1) - abs(d2);
if( d != 0 )
return d;

if( d1 != d2 ) // one postive, one negative
return ( d1 > 0 ) ? -1 : 1;

// d1 == d2
int p = ((index_st*)i1)->p_digit, q = ((index_st*)i2)->p_digit;
if( d1 > 0 )
return p - q;
else
return q - p;
}

int main() {
int N, K, min, min_base, tmp;
int i,j;
scanf("%d %d", &N, &K);
scanf("%s", in_digits);
for( i=0;i<N;i++ )
in_digits[i] -= '0';

min = 0x7fffffff;
for( i=0;i<10;i++ ) {
tmp = 0;
//memcpy(gen_digits[i], in_digits, sizeof(char) * N);
for( j=0;j<N;j++ )
gen_digits[i][j] = in_digits[j];
for( j=0;j<N;j++) { // gen indexs of baseline number i
indexs[i][j].diff = gen_digits[i][j] - i;
indexs[i][j].p_digit = j;
}
qsort(indexs[i], N, sizeof(index_st), index_cmp); // sort indexs by diff
for( j=0;j<K;j++ ) { // set the first K digit to baseline number
tmp += abs(indexs[i][j].diff);
gen_digits[i][indexs[i][j].p_digit] = i;
}

if( min > tmp ) {
min = tmp;
min_base = i;
}
else if( min == tmp ) { // compare lexicographic order
for( j=0;j<N;j++ ) {
if( gen_digits[min_base][j] < gen_digits[i][j] ) // old min_base wins
break;
else if( gen_digits[min_base][j] > gen_digits[i][j] ) { // new i wins
min_base = i;
break;
}
}
}
}

printf("%d\n", min);
for( i=0;i<N;i++ )
printf("%d", gen_digits[min_base][i]);
printf("\n");
return 0;
}



posted @ 2011-10-09 21:30  DOF_KL  阅读(180)  评论(0编辑  收藏  举报