@dmasloff

Как ускорить программу?

Есть такое не сложный, мягко говоря, код, нужно его ускорить, ибо не проходит один тест по времени, как видите ввод/ вывод данных я ускорил, как мог, не вдаваясь в getchar() и какие-то совсем долгие конструкции, так как вообще авторы предполагают, что её и с iostream решить возможно. Тут мы вводим целые n и q; далее вводим массив из n элементов, потом следуют q пар чисел a и b, во время каждой из q итераций цикла мы меняем внутри массива элементы с индексами a-1 и b-1 местами и должны вывести является ли массив отсортированным по неубыванию или нет после каждой из замен.

#include <algorithm>
#include <vector>
#include <stdio.h>
using namespace std;
int main() {
	int n, q;
	scanf("%d%d", &n, &q);
	vector <int> list(n), list1(n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &list[i]);
		list1[i] = list[i];
	}
	sort(list1.begin(), list1.end());
	for (int i = 0; i < q; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		swap(list[a - 1], list[b - 1]);
		if (equal(list.begin(), list.end(), list1.begin())) {
			printf("Sorted!\n");
		}
		else {
			printf("Unsorted!\n");
		}
	}
}
  • Вопрос задан
  • 58 просмотров
Решения вопроса 1
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Надо использовать более умный и быстрый алгоритм. Вы после каждой помены за O(n) проверяете, что массив отсортирован. когда как можно делать это за O(1) - ведь массив меняется всего в двух местах.

Для понимания алгоритма, сначала сделаем немного другую версию за O(n), а потом соптимизируем до константы.
Вы вместо сравнения с сортированным массивом пройдитесь по массиву и смотрите, что для всех соседних элементов следующий более или равен предыдущему.
Следующий шаг - заведите массив bool на n-1 элемент и храните в нем пометки, что в данной позиции массив отсортирован. При помене местами двух элементов надо пересчитать 4 позиции в этом массиве. Потом пройдитесь по массиву и проверьте, что там все элементы true. Пока все еще работает за линию и еще хранит лишний массив.
А теперь последний шаг - можно не проходиться по массиву bool каждый раз, если поддерживать счетчик, сколько там истинных элементов. После ввода массива list надо будет заполнить массив bool-ов и подсчитать, сколько там true. При перестановке a и b у вас максимум 4 элемента в массиве bool могут поменяться. Вот при этих изменениях вы счетчик пересчитывайте. Просто тупо при каждой записи в этот массив вычтите 1 из счетчика, если текущее там значение true и прибавьте 1, если новое значение true.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы