Add ru version (#1865)

* Add Russian docs site baseline

* Add Russian localized codebase

* Polish Russian code wording

* Update ru code translation.

* Update code translation and chapter covers.

* Fix pythontutor extraction.

* Add README and landing page.

* placeholder of profiles

* Use figures of English version

* Remove chapter paperbook
This commit is contained in:
Yudong Jin
2026-03-28 04:24:07 +08:00
committed by GitHub
parent 2ca570cc33
commit 772183705e
1958 changed files with 108186 additions and 0 deletions
@@ -0,0 +1,3 @@
add_executable(coin_change_greedy coin_change_greedy.cpp)
add_executable(fractional_knapsack fractional_knapsack.cpp)
add_executable(max_capacity max_capacity.cpp)
@@ -0,0 +1,60 @@
/**
* File: coin_change_greedy.cpp
* Created Time: 2023-07-20
* Author: krahets (krahets@163.com)
*/
#include "../utils/common.hpp"
/* Размен монет: жадный алгоритм */
int coinChangeGreedy(vector<int> &coins, int amt) {
// Предположить, что список coins упорядочен
int i = coins.size() - 1;
int count = 0;
// Циклически выполнять жадный выбор, пока не останется суммы
while (amt > 0) {
// Найти монету, которая меньше остатка суммы и наиболее к нему близка
while (i > 0 && coins[i] > amt) {
i--;
}
// Выбрать coins[i]
amt -= coins[i];
count++;
}
// Если допустимое решение не найдено, вернуть -1
return amt == 0 ? count : -1;
}
/* Driver Code */
int main() {
// Жадный подход: гарантирует нахождение глобально оптимального решения
vector<int> coins = {1, 5, 10, 20, 50, 100};
int amt = 186;
int res = coinChangeGreedy(coins, amt);
cout << "\ncoins = ";
printVector(coins);
cout << "amt = " << amt << endl;
cout << "Минимальное количество монет для набора суммы " << amt << " = " << res << endl;
// Жадный подход: не гарантирует нахождение глобально оптимального решения
coins = {1, 20, 50};
amt = 60;
res = coinChangeGreedy(coins, amt);
cout << "\ncoins = ";
printVector(coins);
cout << "amt = " << amt << endl;
cout << "Минимальное количество монет для набора суммы " << amt << " = " << res << endl;
cout << "На самом деле минимальное количество равно 3, а именно 20 + 20 + 20" << endl;
// Жадный подход: не гарантирует нахождение глобально оптимального решения
coins = {1, 49, 50};
amt = 98;
res = coinChangeGreedy(coins, amt);
cout << "\ncoins = ";
printVector(coins);
cout << "amt = " << amt << endl;
cout << "Минимальное количество монет для набора суммы " << amt << " = " << res << endl;
cout << "На самом деле минимальное количество равно 2, а именно 49 + 49" << endl;
return 0;
}
@@ -0,0 +1,56 @@
/**
* File: fractional_knapsack.cpp
* Created Time: 2023-07-20
* Author: krahets (krahets@163.com)
*/
#include "../utils/common.hpp"
/* Предмет */
class Item {
public:
int w; // Вес предмета
int v; // Стоимость предмета
Item(int w, int v) : w(w), v(v) {
}
};
/* Дробный рюкзак: жадный алгоритм */
double fractionalKnapsack(vector<int> &wgt, vector<int> &val, int cap) {
// Создать список предметов с двумя свойствами: вес и стоимость
vector<Item> items;
for (int i = 0; i < wgt.size(); i++) {
items.push_back(Item(wgt[i], val[i]));
}
// Отсортировать по удельной стоимости item.v / item.w в порядке убывания
sort(items.begin(), items.end(), [](Item &a, Item &b) { return (double)a.v / a.w > (double)b.v / b.w; });
// Циклический жадный выбор
double res = 0;
for (auto &item : items) {
if (item.w <= cap) {
// Если оставшейся вместимости достаточно, положить в рюкзак текущий предмет целиком
res += item.v;
cap -= item.w;
} else {
// Если оставшейся вместимости недостаточно, положить в рюкзак часть текущего предмета
res += (double)item.v / item.w * cap;
// Свободной вместимости больше не осталось, поэтому выйти из цикла
break;
}
}
return res;
}
/* Driver Code */
int main() {
vector<int> wgt = {10, 20, 30, 40, 50};
vector<int> val = {50, 120, 150, 210, 240};
int cap = 50;
// Жадный алгоритм
double res = fractionalKnapsack(wgt, val, cap);
cout << "Максимальная стоимость предметов, не превышающая вместимость рюкзака, равна " << res << endl;
return 0;
}
@@ -0,0 +1,39 @@
/**
* File: max_capacity.cpp
* Created Time: 2023-07-21
* Author: krahets (krahets@163.com)
*/
#include "../utils/common.hpp"
/* Максимальная вместимость: жадный алгоритм */
int maxCapacity(vector<int> &ht) {
// Инициализировать i и j так, чтобы они располагались по двум концам массива
int i = 0, j = ht.size() - 1;
// Начальная максимальная вместимость равна 0
int res = 0;
// Выполнять жадный выбор в цикле, пока две доски не встретятся
while (i < j) {
// Обновить максимальную вместимость
int cap = min(ht[i], ht[j]) * (j - i);
res = max(res, cap);
// Сдвигать внутрь более короткую сторону
if (ht[i] < ht[j]) {
i++;
} else {
j--;
}
}
return res;
}
/* Driver Code */
int main() {
vector<int> ht = {3, 8, 5, 2, 7, 7, 3, 4};
// Жадный алгоритм
int res = maxCapacity(ht);
cout << "Максимальная вместимость = " << res << endl;
return 0;
}
@@ -0,0 +1,39 @@
/**
* File: max_product_cutting.cpp
* Created Time: 2023-07-21
* Author: krahets (krahets@163.com)
*/
#include "../utils/common.hpp"
/* Максимальное произведение разрезания: жадный алгоритм */
int maxProductCutting(int n) {
// Когда n <= 3, обязательно нужно выделить одну 1
if (n <= 3) {
return 1 * (n - 1);
}
// Жадно выделить множители 3, где a — число троек, а b — остаток
int a = n / 3;
int b = n % 3;
if (b == 1) {
// Если остаток равен 1, преобразовать одну пару 1 * 3 в 2 * 2
return (int)pow(3, a - 1) * 2 * 2;
}
if (b == 2) {
// Если остаток равен 2, ничего не делать
return (int)pow(3, a) * 2;
}
// Если остаток равен 0, ничего не делать
return (int)pow(3, a);
}
/* Driver Code */
int main() {
int n = 58;
// Жадный алгоритм
int res = maxProductCutting(n);
cout << "Максимальное произведение после разрезания = " << res << endl;
return 0;
}