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

#define OK 1
#define ERROR 0
#define OVERFLOW - 2
typedef int Status;
typedef char SElemType;
#define N 5
#define R 2
#define FMT "%-10.5g"
#define STACK_INIT_SIZE 10
#define STACKINCREMENT 10
typedef struct {
    SElemType * base;
    SElemType * top;
    int stacksize;
}
SqStack;
const int M = (N - R) / (R - 1) + 1 + !!((N - R) % (R - 1));
Status InitStack(SqStack & S) {
    S.base = (SElemType * ) malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if (!S.base) exit(OVERFLOW);
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}
Status Push(SqStack & S, SElemType e) {
    if (S.top - S.base >= S.stacksize) {
        S.base = (SElemType * ) realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
        if (!S.base) exit(OVERFLOW);
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    } * S.top++=e;
    return OK;
}
Status ClearStack(SqStack & S) {
    if (!S.base) exit(OVERFLOW);
    S.top = S.base;
    return OK;
}
Status DestroyStack(SqStack & S) {
    if (S.base) free(S.base);
    return OK;
}
Status CopyStack(SqStack & S, SqStack T) {
    int i;
    if (T.stacksize > S.stacksize) {
        S.base = (SElemType * ) realloc(S.base, T.stacksize * sizeof(SElemType));
        if (!S.base) exit(OVERFLOW);
        S.top = S.base;
        S.stacksize = T.stacksize;
    } else ClearStack(S);
    for (i = 0; i < T.top - T.base; i++) S.base = T.base;
    S.top = S.base + (T.top - T.base);
    return OK;
}
Status ConStack(SqStack & S, SqStack T) {
    int i = S.top - S.base;
    int j = T.top - T.base;
    if (i + j > S.stacksize) {
        S.base = (SElemType * ) realloc(S.base, (S.stacksize + T.stacksize) * sizeof(SElemType));
        if (!S.base) exit(OVERFLOW);
        S.top = S.base + i;
        S.stacksize += T.stacksize;
    }
    for (i = 0; i < j; i++) S.top = T.base;
    S.top += j;
    return OK;
}
Status PrintStack(SqStack S) {
    int i;
    char ch;
    for (i = S.top - S.base - 1; i >= 0; i--) {
        ch = S.base;
        if (ch < 10) printf("%d", ch);
        else printf("%c", ch - 10 + 'A');
    }
    return OK;
}
Status Huffman() {
    int i,
    j,
    k,
    s,
    b[m];
    float p[N],
    t;
    SqStack x,
    a[N];
    printf("\n");
    if (N <= R) {
        printf("Huffman:\n");
        for (i = 0; i < N; i++) printf("%d  ", i);
        exit(0);
    }
    for (i = 0; i < N; i++) {
        printf("p[%d]=", i + 1);
        scanf("%f", &p);
    }
    for (i = 0; i < N - 1; i++) {
        k = i;
        for (j = i + 1; j < N; j++) if (p[j] > p[k]) k = j;
        if (k != i) {
            t = p;
            p = p[k];
            p[k] = t;
        }
    }
    printf("\np:\n");
    for (i = 0; i < N; i++) printf(FMT, p);
    for (j = 1; j < M; j++) {
        t = 0.0;
        if (j == 1) {
            s = N % (R - 1);
            if (s < 2) s += R - 1;
            if (s < 2) s += R - 1;
        } else s += R - 1;
        for (i = N - s; i < N - s + R && i < N; i++) t += p;
        for (i = 0; i < N - s; i++) if (t > p || fabs(t - p) < 1e-5) break;
        b[j] = i;
        for (k = N - s; k > i; k--) p[k] = p[k - 1];
        p = t;
    }
    for (i = 0; i < N; i++) InitStack(a);
    for (i = 0; i < R; i++) Push(a, i);
    s = R - 1;
    for (j = M - 1; j > 0; j--) {
        CopyStack(x, a]);
        for (i = b[j]; i < s; i++) CopyStack(a, a);
        ClearStack(a[s]);
        for (i = 0; i < R && i + s < N; i++) {
            Push(a, i);
            ConStack(a, x);
        }
        s += R - 1;
    }
    printf("\nHuffman:\n");
    for (j = 0; j < N; j++) {
        PrintStack(a[j]);
        printf("  ");
        if ((j + 1) % 5 == 0) printf("\n");
    }
    for (j = 0; j < N; j++) DestroyStack(a[j]);
    return OK;
}
void main() {
    Huffman();
}