Как ускорить данный код?

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Я новичок в питоне, изучаю его по курсам. Проходим вложенные циклы. Решение не проходит по времени по 3 тестам(не знаю каким, но с какими-то большими числами). Помогите пожалуйста минимизировать количество вариантов и условий.
Для заданного натурального числа n найти все тройки натуральных чисел a, b, c таких, что a + b + c = n и a ≤ b ≤ c. Минимизируйте количество условий, которые используются в программе.
Входные данные
На вход программе подается натуральное число n <= 100 000.
Выходные данные
Выведите количество искомых троек.
Python:
n = int(input())
s = 0
for a in range(1, n - 1):
    for b in range(a, n - a):
        if b <= n - a - b:
            s += 1
print(s)
OC: Windows
Python 3.7
 
Последнее редактирование:
  • Мне нравится
Реакции: Student

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Python:
n = int(input())
s = 0
for a in range(1, n // 3 + 1):
    for b in range(a, (n - a) // 2 + 1):
        s += 1
print(s)
На данный момент это.
В вопросах к задаче нашёл такое пояснение:
Формулу решения можно найти аналитически и свести задачу к вычислению арифметического выражения.
По условию нужно минимизировать число условий в программе. В формуле их не будет совсем.
Думаю
Вот так немного быстрее:
Python:
n = int(input())
s = 0
for a in range(1, n // 3 + 1):
    s += len([b for b in range(a, (n - a) // 2 + 1)])
print(s)
А вот так гораздо быстрее:
Python:
n = int(input())
s = 0
for a in range(1, n // 3 + 1):
    s += ((n - a) // 2 + 1 - a)

print(s)
 
Последнее редактирование:
  • Мне нравится
Реакции: andr2004

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
К сожалению Ваш код проходит ещё меньше тестов и выдаёт неправильный ответ.Скорее в сего это происходит из-за того, что в Вашем коде не проверяется с >= b.
Я забыл про условие a ≤ b ≤ c. Насчет ускорения - можно срезать лишние итерации цикла, которые не проходят по условию
if b <= n - a - b:
Python:
n = int(input())
s = 0
for a in range(1, n - 1):
    for b in range(a, n - a):
        if b <= n - a - b:
            s += 1
        else:
            break
print(s)
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Возможно не проходит тесты потому что находит не все комбинации. Вот такой вариант находит больше комбинаций:
Python:
n = int(input())
s = 0
for a in range(n - 1, 0, -1):
    for b in range(n - a, a, -1):
        if a + b < n:
            s += 1
print(s)
 

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Возможно не проходит тесты потому что находит не все комбинации. Вот такой вариант находит больше комбинаций:
Python:
n = int(input())
s = 0
for a in range(n - 1, 0, -1):
    for b in range(n - a, a, -1):
        if a + b < n:
            s += 1
print(s)
К сожалению Ваш код проходит ещё меньше тестов и выдаёт неправильный ответ.Скорее в сего это происходит из-за того, что в Вашем коде не проверяется с >= b.
 
Последнее редактирование:

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Я забыл про условие a ≤ b ≤ c. Насчет ускорения - можно срезать лишние итерации цикла, которые не проходят по условию
if b <= n - a - b:
Python:
n = int(input())
s = 0
for a in range(1, n - 1):
    for b in range(a, n - a):
        if b <= n - a - b:
            s += 1
        else:
            break
print(s)
Тесты по времени всё равно не проходятся, но программа работает быстрее чем моя.
 

Rud356

Модератор
Команда форума
Модератор
Апр 5, 2020
44
21
8
Какой в принципе лимит по времени исполнения стоит, вот в чем вопрос?
 

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Какой в принципе лимит по времени исполнения стоит, вот в чем вопрос?
Как я понял, максимальное время работы 0.099 сек
 

Rud356

Модератор
Команда форума
Модератор
Апр 5, 2020
44
21
8
Вообще в лоб мы тут подумали и с такими значениями не решится задачка, но может оно и не надо? Возможно тут надо смотреть в сторону комбинаторики и посмотреть то, какие варианты вообще есть для решения скажем для первого числа c, поскольку оно должно быть наибольшим. Так же C может быть числом n целиком, а остальные два нулями. Так же можно вычитать из числа C числа и раскидывать по разному их на оставшиеся два, опять же включая ноль и исключая варианты где a>b. Может если собрать какие-то формулы получится, то отпишись.
 

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Вообще в лоб мы тут подумали и с такими значениями не решится задачка, но может оно и не надо? Возможно тут надо смотреть в сторону комбинаторики и посмотреть то, какие варианты вообще есть для решения скажем для первого числа c, поскольку оно должно быть наибольшим. Так же C может быть числом n целиком, а остальные два нулями. Так же можно вычитать из числа C числа и раскидывать по разному их на оставшиеся два, опять же включая ноль и исключая варианты где a>b. Может если собрать какие-то формулы получится, то отпишись.
Ну варианты, что несколько из чисел равны нулю сразу можно отмести,т.к. числа натуральные.Спасибо Вам за советы попробую "добить" задачку)
 

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Python:
n = int(input())
s = 0
for a in range(1, n // 3 + 1):
    for b in range(a, (n - a) // 2 + 1):
        s += 1
print(s)
На данный момент это.
В вопросах к задаче нашёл такое пояснение:
Формулу решения можно найти аналитически и свести задачу к вычислению арифметического выражения.
По условию нужно минимизировать число условий в программе. В формуле их не будет совсем.
Думаю
 

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Вот так немного быстрее:
Python:
n = int(input())
s = 0
for a in range(1, n // 3 + 1):
    s += len([b for b in range(a, (n - a) // 2 + 1)])
print(s)
А вот так гораздо быстрее:
Python:
n = int(input())
s = 0
for a in range(1, n // 3 + 1):
    s += ((n - a) // 2 + 1 - a)

print(s)
Огромное спасибо!!!!Сидел,думал над ней целую неделю. Я думаю,пока просто мне не хватает практики.Ещё раз спасибо!!
 

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Вот так немного быстрее:
Python:
n = int(input())
s = 0
for a in range(1, n // 3 + 1):
    s += len([b for b in range(a, (n - a) // 2 + 1)])
print(s)
А вот так гораздо быстрее:
Python:
n = int(input())
s = 0
for a in range(1, n // 3 + 1):
    s += ((n - a) // 2 + 1 - a)

print(s)
В последней строчке (n - a) // 2 + 1 - это количество вариантов b,далле вычитаем а для того,чтобы исключить из подсчёта варианты где а>b.Правильно ли я разобрался?
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
В последней строчке (n - a) // 2 + 1 - это количество вариантов b,далле вычитаем а для того,чтобы исключить из подсчёта варианты где а>b.Правильно ли я разобрался?
Правильно
 
  • Мне нравится
Реакции: andr2004

andr2004

Новичок
Пользователь
Апр 7, 2020
24
4
3
Спасибо за помощь!!
 

Форум IT Специалистов