Untitled

 avatar
unknown
plain_text
a month ago
5.8 kB
4
Indexable
#include <stdio.h>
#include <math.h>

typedef struct {
    int pos;
    int ord;
    int val;
    int grp;
    double ordRel;
    int prm;
} Info;

double valor_referencia(int num_grupos) {
    double p = 0.95;
    double df = num_grupos - 1;
    double a = (p < 0.5) ?  sqrt(-2.0 * log(p)) : sqrt(-2.0 * log(1.0 - p));
    double poly = 2.515517 + 0.802853 * a + 0.010328 * a * a;
    double q = 1.0 + 1.432788 * a + 0.189269 * a * a + 0.001308 * a * a * a;
    double z = (p < 0.5) ? -(a - poly / q) : (a - poly / q);
    double x = df * pow(1.0 - 2.0 / (9.0 * df) + z * sqrt(2.0 / (9.0 * df)), 3.0);
    return x;
}

int lerGrupos(int g, int tamanhos[], int grupos[][100]) {
    int n = 0;

    for (int i = 0; i < g; i++) {
        if (scanf("%d", &tamanhos[i]) != 1) {
            printf("Erro ao ler o tamanho do grupo.\n");
            return -1;
        }

        for (int j = 0; j < tamanhos[i]; j++) {
            if (scanf("%d", &grupos[i][j]) != 1) {
                printf("Erro ao ler os valores do grupo.\n");
                return -1;
            }
            n++;
        }
    }

    return n;
}

void preencherInformacoes(int g, int tamanhos[], int grupos[][100], Info informacoes[]) {
    int pos = 0;
    for (int i = 0; i < g; i++) {
        for (int j = 0; j < tamanhos[i]; j++) {
            informacoes[pos].pos = j;
            informacoes[pos].ord = j + 1;
            informacoes[pos].val = grupos[i][j];
            informacoes[pos].grp = i + 1;
            informacoes[pos].ordRel = 0.0;
            informacoes[pos].prm = 0;
            pos++;
        }
    }
}


void sort(Info informacoes[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (informacoes[j].val > informacoes[j + 1].val) {
                Info temp = informacoes[j];
                informacoes[j] = informacoes[j + 1];
                informacoes[j + 1] = temp;
            }
        }
    }
}


void calcularOrdRel(Info informacoes[], int n) {
    int i = 0;

    while (i < n) {
        int j = i + 1;

        while (j < n && informacoes[j].val == informacoes[i].val) {
            j++;
        }

        int soma_ord = 0;
        for (int k = i; k < j; k++) {
            soma_ord += informacoes[k].ord;
        }

        double media_ord = (double)soma_ord / (j - i);

        for (int k = i; k < j; k++) {
            informacoes[k].ordRel = media_ord;
        }

        i = j;
    }
}

void calcularPrm(Info informacoes[], int n) {
    int i = 0;
    while (i < n) {
        int j = i + 1;
        while (j < n && informacoes[j].val == informacoes[i].val) {
            j++;
        }
        for (int k = i; k < j; k++) {
            informacoes[k].prm = i;
        }
        i = j;
    }
}


void imprimirTabela(Info informacoes[], int n) {
    printf("%s"," Pos  Ord  Grp     OrdRel  Val  Prm\n");

    for (int i = 0; i < n; i++) {
        printf("%4d %4d %4d %10.1f %4d %4d\n",
               i,
               informacoes[i].ord,
               informacoes[i].grp,
               informacoes[i].ordRel,
               informacoes[i].val,
               informacoes[i].prm);
    }
}


void mediaOrdemRelativa(Info informacoes[], int g, int n, double mediasGrupos[]) {
    int contadoresGrupos[g];

    for (int i = 0; i < g; i++) {
        contadoresGrupos[i] = 0;
        mediasGrupos[i] = 0.0;
    }

    for (int j = 0; j < n; j++) {
        int grupo = informacoes[j].grp - 1;
        mediasGrupos[grupo] += informacoes[j].ordRel;
        contadoresGrupos[grupo]++;
    }

    for (int i = 0; i < g; i++) {
        if (contadoresGrupos[i] > 0) {
            mediasGrupos[i] /= contadoresGrupos[i];
        }
    }
}

double calcular_S(Info informacoes[], int g, double mediasGrupos[], double mediaTotal, int n) {
    double S = 0.0;
    for (int i = 0; i < g; i++) {
        int tg = 0;
        for (int j = 0; j < n; j++) {
            if (informacoes[j].grp == i + 1) {
                tg++;
            }
        }
        double diferenca = mediasGrupos[i] - mediaTotal;
        S += tg * (diferenca * diferenca);
    }
    return S;
}

double calcular_X(int n, double S) {
    double numerador = (n - 1) * 12.0 * S;
    double denominador = n * (n * n - 1);
    return numerador / denominador;
}

void compararX(double x, int g) {
    double ref = valor_referencia(g);
    printf("%s%.2f\n","Calc: ", x);
    printf("%s%.2f\n"," Ref: ", ref);
    printf("%s\n", (x < ref) ? "Nao" : "Sim");
}

void imprimirSegundaTabela(double mediasGrupos[], int g, double todos) {
    printf("\n  Grp MediaOrdem\n");
    for (int i = 0; i < g; i++) {
        printf(" %4d %10.1f\n", i + 1, mediasGrupos[i]);
    }
    printf("Todos %10.1f\n\n", todos);
}

int main() {
    int g;

    if (scanf("%d", &g) != 1) return 1;

    int tamanhos[g];
    int grupos[g][100];

    int n = lerGrupos(g, tamanhos, grupos);
    if (n == -1) return 1;


    Info informacoes[n];
    preencherInformacoes(g, tamanhos, grupos, informacoes);

    sort(informacoes, n);

    for (int i = 0; i < n; i++) {
        informacoes[i].ord = i + 1;
    }

    calcularOrdRel(informacoes, n);
    calcularPrm(informacoes, n);

    double mediasGrupos[g];
    mediaOrdemRelativa(informacoes, g, n, mediasGrupos);
    double todos = (double)(n + 1) / 2.0;

    imprimirTabela(informacoes, n);
    imprimirSegundaTabela(mediasGrupos, g, todos);

    double mediaTotal = (double)(n + 1) / 2.0;
    double S = calcular_S(informacoes, g, mediasGrupos, mediaTotal, n);
    double X = calcular_X(n, S);
    compararX(X, g);

    return 0;
}
Editor is loading...
Leave a Comment