Forwarded from Репетитор IT men
📜 Математика количества счастливых билетов
Давайте сегодня подумаем, а как посчитать или хотя бы оценить количество счастливых билетов при 6-значном номере? Можно ли решить такую задачу аналитически?
Давайте для интереса определим верхнюю границу количества таких билетов? Их явно меньше миллиона, верно? А может есть ещё какое-то число?
Пожалуй, это самые подробные в интернете разборы задачи про счастливые билеты. Почему-то эти статьи собрали мало охватов на Дзен. Так что если вы пропустили данные заметки, то ознакомьтесь. Там много интересного с точки зрения математики и алгоритмов. Статьи приведены в порядке возрастания сложности.
👨🏻💻 Задачка про счастливый билет : решаем на Python
📜 Математика количества счастливых билетов
#задачи #разбор_задач #программирование #информатика #олимпиады
💡 Репетитор IT mentor // @mentor_it
Давайте сегодня подумаем, а как посчитать или хотя бы оценить количество счастливых билетов при 6-значном номере? Можно ли решить такую задачу аналитически?
Давайте для интереса определим верхнюю границу количества таких билетов? Их явно меньше миллиона, верно? А может есть ещё какое-то число?
Пожалуй, это самые подробные в интернете разборы задачи про счастливые билеты. Почему-то эти статьи собрали мало охватов на Дзен. Так что если вы пропустили данные заметки, то ознакомьтесь. Там много интересного с точки зрения математики и алгоритмов. Статьи приведены в порядке возрастания сложности.
👨🏻💻 Задачка про счастливый билет : решаем на Python
📜 Математика количества счастливых билетов
#задачи #разбор_задач #программирование #информатика #олимпиады
💡 Репетитор IT mentor // @mentor_it
👍25❤15🔥5🗿2🤔1🤯1😱1
This media is not supported in your browser
VIEW IN TELEGRAM
Задумывались ли вы, как «увидеть» невидимое? Электрическое поле окружает нас повсюду, от розетки до экрана смартфона. Давайте разберемся, как смоделировать его для точечных зарядов и сложных поверхностей и получить эти завораживающие картинки силовых линий и эквипотенциалей.
1. Фундамент: Главные Уравнения
▪️ Закон Кулона для точечного заряда:
F = k * (q₁ * q₂) / r² . Но для поля удобнее работать с напряженностью E = F / q.▪️ Принцип суперпозиции: Поле системы зарядов — это просто векторная сумма полей от каждого заряда в отдельности. Это наше главное оружие в моделировании.
2. Силовые Линии и Эквипотенциали
Поле можно описывать по-разному, и это ключ к красивой визуализации.
▪️Силовые линии (Графическое отображение напряженности E):
— Воображаемые линии, касательные к которым в каждой точке совпадают с вектором E.
— Свойства: Начинаются на «+» зарядах, заканчиваются на «-» или уходят в бесконечность. Никогда не пересекаются!
— Густота линий пропорциональна величине напряженности.
▪️Эквипотенциальные поверхности (Графическое отображение потенциала φ):
— Что это? Поверхности, где потенциал постоянен (φ = const).
— Свойства: Всегда перпендикулярны силовым линиям. Работа по перемещению заряда вдоль такой поверхности равна нулю.
3. Как Строить Уравнения?
Для точечного заряда q в точке (x₀, y₀):
— Потенциал: φ(x, y) = k * q / sqrt( (x - x₀)² + (y - y₀)² )
— Вектор напряженности E: Eₓ = -∂φ/∂x, Eᵧ = -∂φ/∂y (это просто частные производные, градиент со знаком минус).
А как получить уравнение силовой линии? Это уже сложнее. Силовая линия — это кривая, которая в каждой точке направлена вдоль E. Математически это решается через дифференциальное уравнение:
dx / Eₓ(x, y) = dy / Eᵧ(x, y). Решая его (часто численно!), мы получаем траектории для наших визуализаций.4. Инструменты для Моделирования и Визуализации
▪️Python — король научной визуализации: Библиотеки: matplotlib, numpy, scipy.
▪️Как: Задаете сетку точек (x, y), для каждой считаете Eₓ и Eᵧ (суммируя вклады от всех зарядов). Затем:
— Для силовых линий: используйте matplotlib.streamplot
— Для эквипотенциалей: matplotlib.contour или contourf для потенциала φ.
import numpy as np
import matplotlib.pyplot as plt
# Создаем сетку
x = np.linspace(-2, 2, 100)
y = np.linspace(-2, 2, 100)
X, Y = np.meshgrid(x, y)
# Задаем заряды (q, x, y)
charges = [(1, -0.5, 0), (-1, 0.5, 0)]
# Вычисляем полные Eₓ и Eᵧ на сетке
Ex = np.zeros(X.shape)
Ey = np.zeros(Y.shape)
k = 9e9
for q, xq, yq in charges:
R = np.sqrt((X - xq)**2 + (Y - yq)**2)
Ex += k * q * (X - xq) / R**3
Ey += k * q * (Y - yq) / R**3
# Рисуем силовые линии
plt.streamplot(X, Y, Ex, Ey, color='blue', linewidth=1, density=2)
plt.show()
Готовые симуляторы:
— PhET Interactive Simulations (отлично для начального понимания).
— Falstad's E&M Simulator (очень наглядно).
— Comsol Multiphysics, Ansys — для серьезного моделирования сложных поверхностей.
💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
5❤81👍49🔥20🤔4⚡2🤩2🗿1
Есть два самых популярных способа создания строк:
1 —
String s1 = new String("Hello"); 2 —
String s2 = "Hello"; Разберем отличия.
▪️ 1. Место в памяти (Самое главное отличие) — Это отличие является корнем всех остальных различий.
🔸
String s1 = new String("Hello"); (Оператор new) ➖ Создает новый объект в Куче (Heap), независимо от того, какая строка там уже существует.
➖ Каждый вызов new String("Hello") гарантированно создает новый, уникальный объект в памяти.
🔸
String s2 = "Hello"; (Строковый литерал)➖ Строка создается и помещается в специальную область памяти — String Pool (Пул строк), который находится внутри кучи.
➖ Механизм String Pool: Перед созданием новой строки JVM проверяет, нет ли уже строки с таким же значением в пуле. Если есть — переменной просто присваивается ссылка на существующий объект. Если нет — тогда в пуле создается новый объект.
Наглядная аналогия:
➖ new String("Hello") — покупка нового, уникального экземпляра книги, даже если она уже есть в библиотеке.
➖ "Hello" — взятие книги из библиотеки. Если книга есть — вы получаете именно её. Если нет — библиотека сначала покупает новую, а вы её берете.
▪️ 2. Поведение при сравнении (==). Оператор == сравнивает ссылки на объекты, а не их содержимое. Из-за различий в памяти поведение будет разным.
String s1 = new String("Hello");
String s2 = "Hello";
String s3 = "Hello";
System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // true➖ s1 == s2 -> false, потому что s1 ссылается на объект в куче, а s2 — на объект в String Pool. Это два разных объекта в памяти.
➖ s2 == s3 -> true, потому что обе переменные ссылаются на один и тот же объект в String Pool.
Для сравнения содержимого строк всегда используйте метод equals():
System.out.println(s1.equals(s2)); // true (сравнивается содержимое "Hello")
System.out.println(s2.equals(s3)); // true
▪️ 3. Производительность
🔸Строковый литерал ("Hello") — более эффективен. Он избегает создания дубликатов в памяти, что экономит память и ускоряет работу, так как не нужно создавать новый объект, если он уже существует в пуле.
🔸Оператор new — менее эффективен. Он принудительно создает новый объект в куче, даже если идентичная строка уже существует. Это может привести к избыточному расходу памяти.
▪️ 4. Количество создаваемых объектов
🔸
String s1 = new String("Hello"); — Может создать 1 или 2 объекта.➖ 1. Строковый литерал "Hello" сначала ищется в String Pool. Если его нет — он создается в пуле. (Первый возможный объект).
➖ 2. Затем ключевое слово new создает новый объект String в куче. (Второй объект).
Таким образом, если строка "Hello" ранее не существовала в пуле, эта строка кода создаст два объекта.
🔸
String s2 = "Hello";➖ Создает 0 или 1 объект.
➖ JVM ищет "Hello" в String Pool. Если находит — объект не создается, переменной присваивается существующая ссылка (0 новых объектов).
➖ Если не находит — создает новый объект в String Pool (1 новый объект).
▪️Метод intern() — мостик между двумя подходами. Метод intern() позволяет вручную поместить строку из кучи в String Pool или получить ссылку на уже существующую там строку.
String s1 = new String("Hello");
String s2 = s1.intern(); // Помещаем строку в пул (или получаем ссылку из пула)
String s3 = "Hello";
System.out.println(s1 == s2); // false, т.к. s1 все еще в куче
System.out.println(s2 == s3); // true, т.к. s2 и s3 ссылаются на один объект в пулеВ этом примере
s1.intern() находит строку "Hello" в пуле (которая была создана при вычислении литерала внутри конструктора) и возвращает на неё ссылку, которую мы присваиваем s2.Практический вывод: Почти всегда следует использовать строковые литералы (
String s = "value";). Этот способ более эффективен по памяти и времени, так как использует механизм пула строк. #java #задачи #программирование #собеседования #IT #структуры_данных💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤27👍21🔥7✍2❤🔥2👨💻2⚡1
В Java существует важное правило (контракт):
1. Если две строки равны по
equals(), то их hashCode() ДОЛЖЕН быть одинаковым2. Обратное не обязательно верно: одинаковый
hashCode() не гарантирует равенства строкString s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1.equals(s2)); // true
System.out.println(s1.hashCode() == s2.hashCode()); // true
System.out.println(s1.equals(s3)); // true
System.out.println(s1.hashCode() == s3.hashCode()); // true
Метод hashCode() в классе String вычисляется на основе содержимого строки:
public int hashCode() {
int h = hash; // кэшированное значение
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}➖ Вычисляется по формуле:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]➖ Результат кэшируется в поле hash для производительности
➖ Для одинакового содержимого всегда одинаковый hashCode, независимо от того, как была создана строка
➖ value и hash — являются полями класса String и уже существуют в объекте, когда вызывается метод hashCode().
value — массив символов, который хранит собственно содержимое строки. Он инициализируется при создании объекта.
String s = "Hello"; // value = {'H', 'e', 'l', 'l', 'o'}hash — поле для кэширования вычисленного хэш-кода. Оно инициализируется по умолчанию значением 0.
Практическое применение в коллекциях: Связь hashCode и equals критически важна для работы хэш-коллекций:
🔸 HashMap/HashSet
Map<String, Integer> map = new HashMap<>();
map.put("Hello", 1);
map.put(new String("Hello"), 2); // Затрет предыдущее значение!
System.out.println(map.size()); // 1 - потому что ключи равны по equals()
1. Сначала сравниваются hashCode() — если разные, объекты точно разные
2. Если hashCode одинаковые, тогда вызывается equals() для точной проверки
🔸 Оптимизация сравнения
String s1 = "very long string ...";
String s2 = "another very long string ...";
// Сначала проверяется hashCode - быстрая операция
if (s1.hashCode() == s2.hashCode() && s1.equals(s2)) {
// Строки точно равны
}
▪️ 1. Коллизии хэшей — Разные строки могут иметь одинаковый hashCode (хэш-коллизия)
String a = "Aa";
String b = "BB";
System.out.println(a.hashCode()); // 2112
System.out.println(b.hashCode()); // 2112
System.out.println(a.equals(b)); // false
▪️ 2. Производительность
// Медленно - создается новый объект и вычисляется hashCode
String s1 = new String("Hello");
// Быстро - используется кэшированный hashCode из String Pool
String s2 = "Hello";
3. String Pool и hashCode
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
// Все три имеют одинаковый hashCode, но разные способы создания
System.out.println(s1.hashCode()); // одинаковый
System.out.println(s2.hashCode()); // одинаковый
System.out.println(s3.hashCode()); // одинаковый
🔍 Важные моменты. HashCode тесно связан со сравнением строк через:
1. Контракт Java — равные строки по equals() должны иметь одинаковый hashCode
2.. Оптимизацию сравнения — хэш используется для быстрой предварительной проверки
3. Работу коллекций — HashMap, HashSet и другие используют эту связь для эффективного хранения и поиска
#java #задачи #программирование #собеседования #IT #структуры_данных
💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤29👍22🔥7❤🔥4👨💻3😱1