SPOJ PP0604A - Średnia arytmetyczna

0

Treść zadania:
W tablicy n liczb całkowitych dodatnich znajdź tę, której wartość jest najbliższa warości średniej z wszystkich liczb.

Input
Najpierw t < 101 - liczba testów. W kolejnych liniach, dla każdego testu, liczba 0 < n < 100 i n liczb całkowitych dodatnich nie większych niż 100.

Output
Dla każdego testu, w kolejnych liniach, jedna liczba - pierwszy element tablicy, którego wartość jest najbliższa wartości średniej.

Example
Input:
3
4 1 2 3 4
4 4 3 2 1
4 0 3 2 4

Output:
2
3
2

Mój kod:

#include <iostream>

int main() {
	int T, modulo, outcome;
	double sum, average, num;
	int * tab;
	std::cin >> T;
	for (int t = 0; t < T; ++t) {
		sum = 0.0;
		outcome = 0;
		std::cin >> num;
		int number = num;
		tab = new int[number];
		for (int i = 0; i < num; ++i) {
			std::cin >> tab[i];
		}
		for (int j = 0; j < num; ++j) {
			sum += tab[j];
		}
		average = sum / num;
		average *= 10;
		modulo = (int)average % 10;
		average /= 10;
		if (modulo < 5) {
			for (int k = 0; k < num; ++k) {
				if (tab[k] > outcome && tab[k] <= average) {
					outcome = tab[k];
				}
			}
			std::cout << outcome << "\n";
		}
		else if (modulo > 5) {
			outcome = 100;
			for (int l = 0; l < num; ++l) {
				if (tab[l] < outcome && tab[l] >= average) {
					outcome = tab[l];
				}
			}
			std::cout << outcome << "\n";
		}
		else {
			int a, b;
			for (int k = 0; k < num; ++k) {
				if (tab[k] > outcome && tab[k] <= average) {
					a = tab[k];
				}
			}
			outcome = 100;
			for (int l = 0; l < num; ++l) {
				if (tab[l] < outcome && tab[l] >= average) {
					b = tab[l];
				}
			}
			for (int l = 0; l < num; ++l) {
				if (tab[l] == a) {
					std::cout << a << "\n";
					break;
				}
				else if (tab[l] == b) {
					std::cout << b << "\n";
					break;
				}
			}
		}
	}
	return 0;
}

Cały czas dostaję komunikat o błędnej odpowiedzi. Prosiłbym o pomoc.

0

Ten kod jest dość mocno nieczytelny. Podziel sobie go na wczytywanie/parsowanie linii, liczenie średniej, szukanie liczby najbliżej średniej (jako osobne funkcje) i operuj na nich. Łatwiej będzie Ci też sprawdzać poprawność.

Nie baw się też w ręczną alokację ( https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete ), tylko użyj std::vector. A gdybyś jezcze użył std::accumulate i std::min_element (albo max, bez znaczenia) to całe zadanie można ogarnąć w kilka linijek ;​)

0

Wydaje mi się że zdrowo przekombinowałeś, zapoznaj się z fabs() a potem napisz to jeszcze raz

1

Spróbuj inaczej, bo ten fragment:

        average *= 10;
        modulo = (int)average % 10;
        average /= 10;

i kontynuacja na nim oparta, produkuje bugi na 100%.

1

Spróbowałbym tak, mając już średnią, average, ustawiłby się na poczatek tablicy i:

  • ustalił minimum początkowe, min_start na +-*tab - average, plus minus, w zależności czy dodatnie czy ujemne, tak żeby było dodatnie;
  • i w pętli tak samo ustalając już aktualne różnice, porównywał je z z minimum początkowym i je [to minimum]aktualizował.
    Na końcu wystarczy zwrócić tab[aktualny_indeks].
0

Wersja z użyciem STL. Nie jest to najbardziej wydajna implementacja algorytmu, ale na pewno jedna z tych najkrótszych.

#include <iostream>
#include <vector>
#include <set>
#include <numeric>

using namespace std;

int main()
{
    vector<int> data {4,67,2,43,87,21,36,61,9,6,19,51,52,33};
    set<pair<double,int>> diff;

    auto average = accumulate( data.begin() , data.end() , 0.0 )/data.size();
    for( const auto& element : data )
    {
        diff.insert({abs(average-element),element});
    }

    cout << "Average is : " << average  << " , close value to average is : " << (*diff.begin()).second << "\n";

    return 0;
}
0

Takie zadanka się golfuje, bro.

89 znaków. Kto da mniej.

for a in[*open(0)][1:]:b,*c=map(int,a.split());print(min(c,key=lambda d:abs(sum(c)/b-d)))

1 użytkowników online, w tym zalogowanych: 0, gości: 1