init commit
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
// #include <iostream>
|
||||
// #include <array>
|
||||
// #include <cstdint>
|
||||
|
||||
class BlackHole {
|
||||
int mass;
|
||||
public:
|
||||
BlackHole(size_t mass) : mass(mass) {}
|
||||
|
||||
size_t get_mass() const {
|
||||
return mass;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void consume(T* arg) {
|
||||
if (arg == nullptr) {
|
||||
std::cout << "There is nothing to consume" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t arg_mass = sizeof(*arg);
|
||||
if (std::is_const<T>::value) {
|
||||
std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl;
|
||||
} else {
|
||||
std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl;
|
||||
}
|
||||
|
||||
mass += arg_mass;
|
||||
delete arg;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void consume(void* arg) {
|
||||
throw std::runtime_error("Black hole has tried to consume void");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void consume(const void* arg) {
|
||||
throw std::runtime_error("Black hole has tried to consume void");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void consume(BlackHole* arg) {
|
||||
if (arg == this) {
|
||||
throw std::runtime_error("Black hole has tried to consume itself");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
size_t arg_mass = arg->get_mass();
|
||||
if (std::is_const<BlackHole>::value) {
|
||||
std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl;
|
||||
} else {
|
||||
std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl;
|
||||
}
|
||||
|
||||
mass += arg_mass;
|
||||
delete arg;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void consume(const BlackHole* arg) {
|
||||
if (arg == this) {
|
||||
throw std::runtime_error("Black hole has tried to consume itself");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
size_t arg_mass = arg->get_mass();
|
||||
if (std::is_const<BlackHole>::value) {
|
||||
std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl;
|
||||
} else {
|
||||
std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl;
|
||||
}
|
||||
|
||||
mass += arg_mass;
|
||||
delete arg;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void consume(T arg) {
|
||||
throw std::runtime_error("Black hole has tried to consume non-pointer");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
~BlackHole() = default;
|
||||
};
|
||||
|
||||
/*
|
||||
Требуется реализовать класс BlackHole.
|
||||
|
||||
1) Конструктор класса должен принимать аргумент типа size_t, задающий массу чёрной дыры.
|
||||
|
||||
2) У класса должен быть метод get_mass() возвращающий текущую массу.
|
||||
|
||||
3) У класса должен быть шаблонный метод consume(arg), предназначенный для "поглощения" указателей (см. ниже) и способный принимать аргументы любых типов.
|
||||
|
||||
Вызов consume должен вести себя следующим образом.
|
||||
|
||||
1) Он должен выбрасывать исключение типа runtime_error (тексты исключений следует взять из примера вывода ниже) в следующих ситуациях:
|
||||
|
||||
- При передаче ему аргумента, не являющегося указателем
|
||||
|
||||
- Если переданный указатель указывает на void (константный или неконстантный)
|
||||
|
||||
- Если чёрная дыра пытается поглотить саму себя
|
||||
|
||||
2) Если в качестве аргумента передан нулевой указатель, следует напечатать "There is nothing to consume" и ничего не делать.
|
||||
|
||||
3) Если ни одно из выше перечисленных условий не сработало, то аргумент считается корректным указателем и для него нужно выполнить следующие действия:
|
||||
|
||||
- Определить "массу" аргумента. Для BlackHole масса определяется через вызов get_mass(), для остальных - через размер указываемого типа в байтах.
|
||||
|
||||
- Напечатать "Black hole consumed N non-const bytes", где вместо N нужно подставить массу аргумента. Если в качестве аргумента передан указатель на константный тип, то вместо non-const следует печатать const.
|
||||
|
||||
- Добавить массу аргумента к текущей массе чёрной дыры.
|
||||
|
||||
- Удалить аргумент через вызов delete.
|
||||
|
||||
При подстановке решения студента, следующий код должен работать:
|
||||
*/
|
||||
|
||||
// int main() {
|
||||
// BlackHole hole(100);
|
||||
// std::cout << "The initial mass is " << hole.get_mass() << " bytes" << std::endl;
|
||||
|
||||
// hole.consume(new int64_t);
|
||||
// hole.consume(const_cast <const int64_t*>(new int64_t));
|
||||
// hole.consume(new int32_t);
|
||||
// hole.consume(static_cast<char*>(nullptr));
|
||||
// hole.consume(new BlackHole{ 50 });
|
||||
// hole.consume(new std::array<char, 64>);
|
||||
|
||||
// try {
|
||||
// hole.consume(5);
|
||||
// }
|
||||
// catch (std::runtime_error& err) {
|
||||
// std::cout << "Error: " << err.what() << std::endl;
|
||||
// }
|
||||
|
||||
// try {
|
||||
// hole.consume(&hole);
|
||||
// }
|
||||
// catch (std::runtime_error& err) {
|
||||
// std::cout << "Error: " << err.what() << std::endl;
|
||||
// }
|
||||
|
||||
// try {
|
||||
// hole.consume((void*) nullptr);
|
||||
// }
|
||||
// catch (std::runtime_error& err) {
|
||||
// std::cout << "Error: " << err.what() << std::endl;
|
||||
// }
|
||||
|
||||
// std::cout << "The total mass is: " << hole.get_mass() << " bytes" << std::endl;
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
@@ -0,0 +1,105 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
/*
|
||||
Количество слов
|
||||
|
||||
Напишите программу, которая для заданного ДКА и заданной максимальной длины N выводит общее количество слов не длинее N, допускаемых данным ДКА.
|
||||
|
||||
На вход программе подаётся описание ДКА в виде непустых строк следующих следующих видов.
|
||||
|
||||
1) Переход из состояния номер 1 в состояние номер 2 по символу "a":
|
||||
|
||||
[1] a [2]
|
||||
|
||||
2) Обозначение того, что состояние номер 3 является допускающим:
|
||||
|
||||
[[3]]
|
||||
|
||||
3) Явное объявление состояния под номером 4 (например, на случай если оно не фигурирует ни в каких переходах и не является допускающим):
|
||||
|
||||
[4]
|
||||
|
||||
После описания ДКА идёт пустая строка, за ней число N.
|
||||
|
||||
Номера состояний - это целые неотрицательные числа, в алфавит ДКА входят только строчные символы латинского алфавита.
|
||||
|
||||
Число N не может быть больше 100, а ответ помещается в тип size_t.
|
||||
|
||||
Начальным состоянием считается то, которое было первым объявлено в описании ДКА (либо в явном виде, либо при описании перехода).
|
||||
Примеры
|
||||
Входные данные в файле noMore.in
|
||||
|
||||
[0] a [1]
|
||||
[1] a [0]
|
||||
[1] b [0]
|
||||
[[0]]
|
||||
|
||||
4
|
||||
|
||||
Результат работы в файле noMore.out
|
||||
|
||||
7
|
||||
*/
|
||||
|
||||
int main() {
|
||||
std::regex state_declaration_pattern(R"(\[(\d+)\])");
|
||||
std::regex transition_pattern(R"(\[(\d+)\]\s*([a-z])\s*\[(\d+)\])");
|
||||
std::regex accepting_state_pattern(R"(\[\[(\d+)\]\])");
|
||||
|
||||
std::map<int, std::map<char, int>> state_transitions;
|
||||
std::set<int> accepting_states;
|
||||
int start_state = -1;
|
||||
|
||||
std::ifstream Input("noMore.in");
|
||||
std::string line;
|
||||
|
||||
while (std::getline(Input, line)) {
|
||||
std::smatch match_result;
|
||||
|
||||
if (start_state == -1 && std::regex_match(line, match_result, state_declaration_pattern)) {
|
||||
start_state = std::stoi(match_result[1].str());
|
||||
} else if (std::regex_match(line, match_result, transition_pattern)) {
|
||||
start_state = start_state == -1 ? std::stoi(match_result[1].str()) : start_state;
|
||||
state_transitions[std::stoi(match_result[1].str())][match_result[2].str()[0]] = std::stoi(match_result[3].str());
|
||||
} else if (std::regex_match(line, match_result, accepting_state_pattern)) {
|
||||
accepting_states.insert(std::stoi(match_result[1].str()));
|
||||
} else if (line.empty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int max_length;
|
||||
Input >> max_length;
|
||||
Input.close();
|
||||
|
||||
size_t total_count = 0;
|
||||
std::vector<std::map<int, size_t>> dp_table(max_length + 1);
|
||||
dp_table[0][start_state] = 1;
|
||||
|
||||
for (int length = 1; length <= max_length; ++length) {
|
||||
for (const auto& [current_state, count] : dp_table[length - 1]) {
|
||||
for (const auto& [transition_char, next_state] : state_transitions[current_state]) {
|
||||
dp_table[length][next_state] += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int length = 0; length <= max_length; ++length) {
|
||||
for (const auto& [state, count] : dp_table[length]) {
|
||||
if (accepting_states.count(state)) {
|
||||
total_count += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream Output("noMore.out");
|
||||
Output << total_count << std::endl;
|
||||
Output.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
/*
|
||||
Количество слов
|
||||
|
||||
Напишите программу, которая для заданного ДКА и заданной максимальной длины N выводит общее количество слов не длинее N, допускаемых данным ДКА.
|
||||
|
||||
На вход программе подаётся описание ДКА в виде непустых строк следующих следующих видов.
|
||||
|
||||
1) Переход из состояния номер 1 в состояние номер 2 по символу "a":
|
||||
|
||||
[1] a [2]
|
||||
|
||||
2) Обозначение того, что состояние номер 3 является допускающим:
|
||||
|
||||
[[3]]
|
||||
|
||||
3) Явное объявление состояния под номером 4 (например, на случай если оно не фигурирует ни в каких переходах и не является допускающим):
|
||||
|
||||
[4]
|
||||
|
||||
После описания ДКА идёт пустая строка, за ней число N.
|
||||
|
||||
Номера состояний - это целые неотрицательные числа, в алфавит ДКА входят только строчные символы латинского алфавита.
|
||||
|
||||
Число N не может быть больше 100, а ответ помещается в тип size_t.
|
||||
|
||||
Начальным состоянием считается то, которое было первым объявлено в описании ДКА (либо в явном виде, либо при описании перехода).
|
||||
Примеры
|
||||
Входные данные в файле noMore.in
|
||||
|
||||
[0] a [1]
|
||||
[1] a [0]
|
||||
[1] b [0]
|
||||
[[0]]
|
||||
|
||||
4
|
||||
|
||||
Результат работы в файле noMore.out
|
||||
|
||||
7
|
||||
*/
|
||||
|
||||
int main() {
|
||||
std::ifstream inputFile("noMore.in");
|
||||
|
||||
std::string line;
|
||||
std::regex firstLinePattern(R"(\[(\d+)\])");
|
||||
std::regex subsequentLinePattern(R"(\[(\d+)\]\s*([a-z])\s*\[(\d+)\])");
|
||||
std::regex finalLinePattern(R"(\[\[(\d+)\]\])");
|
||||
std::regex emptyLinePattern(R"(\s*)");
|
||||
std::regex numLinePattern(R"(\d+)");
|
||||
|
||||
// Read the first line
|
||||
int start_num = -1;
|
||||
std::map<int, std::map<char, int>> transitions;
|
||||
std::set<int> final_states;
|
||||
|
||||
int n = 0;
|
||||
|
||||
// Read subsequent lines
|
||||
while (std::getline(inputFile, line)) {
|
||||
std::smatch match;
|
||||
if (std::regex_match(line, match, firstLinePattern)) {
|
||||
if (start_num == -1) {
|
||||
start_num = std::stoi(match[1].str());
|
||||
}
|
||||
} else if (std::regex_match(line, match, subsequentLinePattern)) {
|
||||
if (start_num == -1) {
|
||||
start_num = std::stoi(match[1].str());
|
||||
}
|
||||
int fromState = std::stoi(match[1].str());
|
||||
char symbol = match[2].str()[0];
|
||||
int toState = std::stoi(match[3].str());
|
||||
transitions[fromState][symbol] = toState;
|
||||
} else if (std::regex_match(line, match, finalLinePattern)) {
|
||||
final_states.insert(std::stoi(match[1].str()));
|
||||
} else if (std::regex_match(line, match, emptyLinePattern)) {
|
||||
continue;
|
||||
} else if (std::regex_match(line, match, numLinePattern)) {
|
||||
n = std::stoi(match[0].str());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
inputFile.close();
|
||||
|
||||
size_t ans = 0;
|
||||
std::vector<std::map<int, size_t>> dp(n + 1);
|
||||
dp[0][start_num] = 1;
|
||||
for (int k = 1; k <= n; ++k) {
|
||||
for (const auto& [state, count] : dp[k - 1]) {
|
||||
for (const auto& [symbol, nextState] : transitions[state]) {
|
||||
dp[k][nextState] += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int k = 0; k <= n; ++k) {
|
||||
for (const auto& [state, count] : dp[k]) {
|
||||
if (final_states.count(state)) {
|
||||
ans += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream outputFile("noMore.out");
|
||||
outputFile << ans << std::endl;
|
||||
|
||||
outputFile.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
int increment_counter() {
|
||||
static int counter = 0;
|
||||
return counter++;
|
||||
}
|
||||
|
||||
struct Data {
|
||||
public:
|
||||
int value;
|
||||
Data(int x = 42) : value(x) {}
|
||||
Data(const Data& data) {
|
||||
value = data.value;
|
||||
}
|
||||
~Data() {
|
||||
// std::cout << "~Data() called " << std::endl;
|
||||
increment_counter();
|
||||
}
|
||||
Data& operator=(const Data& data) {
|
||||
value = data.value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& os, const Data data) {
|
||||
os << data.value;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
class DataBuffer {
|
||||
Data* addr;
|
||||
size_t size_buf;
|
||||
friend void std::swap(DataBuffer& a, DataBuffer& b);
|
||||
public:
|
||||
DataBuffer(size_t size) {
|
||||
// std::cout << "called11!" << std::endl;
|
||||
size_buf = size;
|
||||
addr = new Data[size_buf];
|
||||
}
|
||||
DataBuffer(const DataBuffer& data_buf) = delete;
|
||||
const DataBuffer& operator=(const DataBuffer& data_buf) = delete;
|
||||
DataBuffer(DataBuffer&& data_buf) noexcept : addr(data_buf.addr), size_buf(data_buf.size_buf) {
|
||||
// std::cout << "Move constructor called!" << std::endl;
|
||||
data_buf.addr = nullptr;
|
||||
data_buf.size_buf = 0;
|
||||
}
|
||||
DataBuffer& operator=(DataBuffer&& data_buf) noexcept {
|
||||
// std::cout << "Move assignment operator called!" << std::endl;
|
||||
if (this != &data_buf) {
|
||||
delete[] addr;
|
||||
addr = data_buf.addr;
|
||||
size_buf = data_buf.size_buf;
|
||||
data_buf.addr = nullptr;
|
||||
data_buf.size_buf = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~DataBuffer() {
|
||||
// std::cout << "called1!" << std::endl;
|
||||
delete[] addr;
|
||||
}
|
||||
size_t size() const {
|
||||
return size_buf;
|
||||
}
|
||||
Data& operator[](const size_t ind) {
|
||||
return addr[ind];
|
||||
}
|
||||
const Data& operator[](const size_t ind) const {
|
||||
return addr[ind];
|
||||
}
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
void swap<DataBuffer>(DataBuffer& a, DataBuffer& b) {
|
||||
std::swap(a.addr, b.addr);
|
||||
std::swap(a.size_buf, b.size_buf);
|
||||
}
|
||||
}
|
||||
|
||||
void print_buffer(const DataBuffer& buffer) {
|
||||
for (size_t i = 0; i < buffer.size(); i++)
|
||||
std::cout << "buffer[" << i << "] == " << buffer[i] << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
{
|
||||
DataBuffer buffer_1{ 5 }, buffer_2{ 3 };
|
||||
|
||||
std::cout << "buffer_1.size() == " << buffer_1.size() << std::endl;
|
||||
std::cout << "buffer_2.size() == " << buffer_2.size() << std::endl;
|
||||
|
||||
for (size_t i = 0; i < buffer_2.size(); i++)
|
||||
buffer_2[i] = i + 1;
|
||||
|
||||
std::cout << "buffer_1[0] == " << buffer_1[0].value << std::endl;
|
||||
std::cout << "buffer_2[0] == " << buffer_2[0].value << std::endl;
|
||||
|
||||
std::swap(buffer_1, buffer_2);
|
||||
// DataBuffer buffer_copy = buffer_1; // forbidden!
|
||||
|
||||
std::cout << "buffer_1.size() == " << buffer_1.size() << std::endl;
|
||||
std::cout << "buffer_2.size() == " << buffer_2.size() << std::endl;
|
||||
|
||||
print_buffer(buffer_1);
|
||||
}
|
||||
std::cout << "~Data() called " << increment_counter() << " times" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#include <iostream>
|
||||
|
||||
class C
|
||||
{
|
||||
unsigned long long x = 0;
|
||||
bool last = false;
|
||||
|
||||
public:
|
||||
C() {
|
||||
if (std::cin >> x) {
|
||||
return;
|
||||
}
|
||||
|
||||
last = true;
|
||||
}
|
||||
|
||||
~C() {
|
||||
if (last) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << x << " ";
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
f() {
|
||||
C c;
|
||||
|
||||
if (std::cin.eof()) {
|
||||
return;
|
||||
}
|
||||
|
||||
f();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main() {
|
||||
f();
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
/*
|
||||
Сортировка
|
||||
|
||||
Необходимо реализовать функцию filter_sort, которая принимает контейнер с произвольным доступом к элементам и три лямбда-функции. Первая лямбда задаёт критерий фильтрации элементов контейнера, вторая - порядок первичной сортировки элементов, третья - вторичной сортировки. Файл с решением должен содержать только реализацию шаблонной функции filter_sort. Тип элементов контейнера при тестировании может быть любым.
|
||||
|
||||
После подстановки вашей реализации, приведенный ниже код должен работать (при тестировании код отличается) и выдавать для примера ввода ниже пример вывода ниже:
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
struct Student {
|
||||
std::string full_name;
|
||||
int group_no;
|
||||
|
||||
void print() const {
|
||||
std::cout << group_no << " " << full_name << std::endl;
|
||||
}
|
||||
|
||||
static std::optional<Student> read() {
|
||||
Student student;
|
||||
if (!(std::cin >> student.group_no))
|
||||
return {};
|
||||
std::cin >> std::ws;
|
||||
if (!std::getline(std::cin, student.full_name))
|
||||
return {};
|
||||
return student;
|
||||
}
|
||||
};
|
||||
|
||||
// Your filter_sort is here!
|
||||
|
||||
template <class T, class Filter, class PSort, class SSort>
|
||||
void filter_sort(T& mas, Filter filter, PSort psort, SSort ssort) {
|
||||
auto it = std::remove_if(mas.begin(), mas.end(), [filter](auto a) { return !filter(a); });
|
||||
|
||||
std::stable_sort(mas.begin(), it, [ssort](auto a, auto b) { return ssort(a, b); });
|
||||
std::stable_sort(mas.begin(), it, [psort](auto a, auto b) { return psort(a, b); });
|
||||
|
||||
mas.erase(it, mas.end());
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::vector<Student> students;
|
||||
while (auto student = Student::read())
|
||||
students.push_back(*student);
|
||||
|
||||
filter_sort(students, // the container
|
||||
[](Student& stud) { return stud.group_no >= 0; }, // filter
|
||||
[](Student& stud_1, Student& stud_2) { return stud_1.group_no < stud_2.group_no; }, // primary sort
|
||||
[](Student& stud_1, Student& stud_2) { return stud_1.full_name < stud_2.full_name; } // secondary sort
|
||||
);
|
||||
|
||||
for (auto& student : students)
|
||||
student.print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Примеры
|
||||
Входные данные
|
||||
|
||||
-100 Иванов Иван
|
||||
300 Забугоркина Афродита
|
||||
0 Смирнова Настя
|
||||
0 Смирнова Анастасия
|
||||
|
||||
Результат работы
|
||||
|
||||
0 Смирнова Анастасия
|
||||
0 Смирнова Настя
|
||||
300 Забугоркина Афродита
|
||||
*/
|
||||
@@ -0,0 +1,90 @@
|
||||
|
||||
/*
|
||||
Сортировка
|
||||
|
||||
Необходимо реализовать функцию filter_sort, которая принимает контейнер с произвольным доступом к элементам и три лямбда-функции. Первая лямбда задаёт критерий фильтрации элементов контейнера, вторая - порядок первичной сортировки элементов, третья - вторичной сортировки. Файл с решением должен содержать только реализацию шаблонной функции filter_sort. Тип элементов контейнера при тестировании может быть любым.
|
||||
|
||||
После подстановки вашей реализации, приведенный ниже код должен работать (при тестировании код отличается) и выдавать для примера ввода ниже пример вывода ниже:
|
||||
|
||||
*/
|
||||
|
||||
// #include <iostream>
|
||||
// #include <vector>
|
||||
// #include <string>
|
||||
// #include <optional>
|
||||
// #include <algorithm>
|
||||
// #include <iterator>
|
||||
|
||||
// struct Student {
|
||||
// std::string full_name;
|
||||
// int group_no;
|
||||
|
||||
// void print() const {
|
||||
// std::cout << group_no << " " << full_name << std::endl;
|
||||
// }
|
||||
|
||||
// static std::optional<Student> read() {
|
||||
// Student student;
|
||||
// if (!(std::cin >> student.group_no))
|
||||
// return {};
|
||||
// std::cin >> std::ws;
|
||||
// if (!std::getline(std::cin, student.full_name))
|
||||
// return {};
|
||||
// return student;
|
||||
// }
|
||||
// };
|
||||
|
||||
// Your filter_sort is here!
|
||||
|
||||
template <typename Container, typename Filter, typename PrimarySort, typename SecondarySort>
|
||||
void filter_sort(Container& container, Filter filter, PrimarySort primary_sort, SecondarySort secondary_sort) {
|
||||
auto it = std::remove_if(container.begin(), container.end(), [=](auto& item) { return !filter(item); });
|
||||
container.erase(it, container.end());
|
||||
|
||||
std::stable_sort(container.begin(), container.end(), [=](auto item1, auto item2) { return secondary_sort(item1, item2); });
|
||||
std::stable_sort(container.begin(), container.end(), [=](auto item1, auto item2) { return primary_sort(item1, item2); });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// std::vector<Student> students;
|
||||
// while (auto student = Student::read())
|
||||
// students.push_back(*student);
|
||||
|
||||
// filter_sort(students, // the container
|
||||
// [](Student& stud) { return stud.group_no >= 0; }, // filter
|
||||
// // [](const Student stud_1, const Student stud_2) { return stud_1.group_no < stud_2.group_no; }, // primary sort
|
||||
// [](Student& stud_1, Student& stud_2) { return stud_1.group_no < stud_2.group_no; }, // primary sort
|
||||
// // [](const Student stud_1, const Student stud_2) { return stud_1.full_name < stud_2.full_name; } // secondary sort
|
||||
// [](Student& stud_1, Student& stud_2) { return stud_1.full_name < stud_2.full_name; } // secondary sort
|
||||
// );
|
||||
|
||||
// // filter_sort(students, // the container
|
||||
// // [](Student& stud) { return stud.group_no >= 0; }, // filter
|
||||
// // [](Student& stud_1, Student& stud_2) { return stud_1.group_no < stud_2.group_no; }, // primary sort
|
||||
// // [](Student& stud_1, Student& stud_2) { return stud_1.full_name < stud_2.full_name; } // secondary sort
|
||||
// // );
|
||||
|
||||
// for (auto& student : students)
|
||||
// student.print();
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
/*
|
||||
|
||||
Примеры
|
||||
Входные данные
|
||||
|
||||
-100 Иванов Иван
|
||||
300 Забугоркина Афродита
|
||||
0 Смирнова Настя
|
||||
0 Смирнова Анастасия
|
||||
|
||||
Результат работы
|
||||
|
||||
0 Смирнова Анастасия
|
||||
0 Смирнова Настя
|
||||
300 Забугоркина Афродита
|
||||
*/
|
||||
@@ -0,0 +1,137 @@
|
||||
// #include <iostream>
|
||||
// #include <type_traits>
|
||||
|
||||
// class ASTNode;
|
||||
|
||||
// class NodeOwner {
|
||||
// ASTNode* node = nullptr;
|
||||
// public:
|
||||
// explicit NodeOwner(ASTNode* node) : node(node) {}
|
||||
|
||||
// NodeOwner(const NodeOwner&) = delete;
|
||||
// NodeOwner& operator=(const NodeOwner&) = delete;
|
||||
// NodeOwner(NodeOwner&& other) { std::swap(node, other.node); }
|
||||
// NodeOwner& operator=(NodeOwner&& other) { std::swap(node, other.node); return *this; }
|
||||
|
||||
// ASTNode* operator->() { return node; }
|
||||
// const ASTNode* operator->() const { return node; }
|
||||
// operator bool() const { return (bool)node; }
|
||||
|
||||
// ~NodeOwner();
|
||||
// };
|
||||
|
||||
/*
|
||||
|
||||
Реализации классов ASTNode, ASTNumberNode, ASTPlusNode и ASTMinusNode.
|
||||
Реализации операторов operator+ и operator-.
|
||||
|
||||
*/
|
||||
|
||||
class ASTNode {
|
||||
public:
|
||||
virtual void print() {}
|
||||
virtual int get_value() { return 0; }
|
||||
virtual ~ASTNode() {}
|
||||
};
|
||||
|
||||
class ASTNumberNode : ASTNode {
|
||||
int value;
|
||||
public:
|
||||
ASTNumberNode(int value) : value(value) {}
|
||||
static NodeOwner create(int value = 0) {
|
||||
return NodeOwner(new ASTNumberNode(value));
|
||||
}
|
||||
|
||||
void print() {
|
||||
std::cout << value;
|
||||
}
|
||||
|
||||
int get_value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
~ASTNumberNode() = default;
|
||||
};
|
||||
|
||||
class ASTPlusNode : ASTNode {
|
||||
NodeOwner left, right;
|
||||
public:
|
||||
ASTPlusNode(NodeOwner left, NodeOwner right) : left(std::move(left)), right(std::move(right)) {}
|
||||
static NodeOwner create(NodeOwner left, NodeOwner right) {
|
||||
return std::move(NodeOwner(new ASTPlusNode(std::move(left), std::move(right))));
|
||||
}
|
||||
|
||||
void print() {
|
||||
std::cout << "(";
|
||||
left->print();
|
||||
std::cout << " + ";
|
||||
right->print();
|
||||
std::cout << ")";
|
||||
}
|
||||
|
||||
int get_value() {
|
||||
return left->get_value() + right->get_value();
|
||||
}
|
||||
|
||||
~ASTPlusNode() = default;
|
||||
};
|
||||
|
||||
class ASTMinusNode : ASTNode {
|
||||
NodeOwner left, right;
|
||||
public:
|
||||
ASTMinusNode(NodeOwner left, NodeOwner right) : left(std::move(left)), right(std::move(right)) {}
|
||||
static NodeOwner create(NodeOwner left, NodeOwner right) {
|
||||
return std::move(NodeOwner(new ASTMinusNode(std::move(left), std::move(right))));
|
||||
}
|
||||
|
||||
void print() {
|
||||
std::cout << "(";
|
||||
left->print();
|
||||
std::cout << " - ";
|
||||
right->print();
|
||||
std::cout << ")";
|
||||
}
|
||||
|
||||
int get_value() {
|
||||
return left->get_value() - right->get_value();
|
||||
}
|
||||
|
||||
~ASTMinusNode() = default;
|
||||
|
||||
};
|
||||
|
||||
NodeOwner operator+(NodeOwner left, NodeOwner right) {
|
||||
return std::move(NodeOwner(ASTPlusNode::create(std::move(left), std::move(right))));
|
||||
}
|
||||
|
||||
NodeOwner operator-(NodeOwner left, NodeOwner right) {
|
||||
return std::move(NodeOwner(ASTMinusNode::create(std::move(left), std::move(right))));
|
||||
}
|
||||
|
||||
|
||||
// NodeOwner::~NodeOwner() {
|
||||
// if (node)
|
||||
// delete node;
|
||||
// }
|
||||
|
||||
// int main() {
|
||||
// // static_assert(std::is_same::value, "ASTNumberNode::create() must return NodeOwner value");
|
||||
// // static_assert(std::is_same::value, "ASTPlusNode::create() must return NodeOwner value");
|
||||
// // static_assert(std::is_same::value, "(NodeOwner + NodeOwner) must return NodeOwner value");
|
||||
|
||||
// auto expr_1 = ASTPlusNode::create(
|
||||
// ASTNumberNode::create(1),
|
||||
// ASTMinusNode::create(
|
||||
// ASTNumberNode::create(2),
|
||||
// ASTNumberNode::create(3)
|
||||
// )
|
||||
// );
|
||||
// expr_1->print();
|
||||
// std::cout << " = " << expr_1->get_value() << std::endl;
|
||||
|
||||
// auto expr_2 = ASTNumberNode::create(4) - ASTNumberNode::create(5) + ASTNumberNode::create(6);
|
||||
// expr_2->print();
|
||||
// std::cout << " = " << expr_2->get_value() << std::endl;
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
@@ -0,0 +1,69 @@
|
||||
// #include <iostream>
|
||||
// #include <memory>
|
||||
// #include <list>
|
||||
// #include <vector>
|
||||
|
||||
// struct Element {
|
||||
// int value;
|
||||
// Element(int value) : value(value) {}
|
||||
// };
|
||||
|
||||
// Реализация функции make_safe_vector()
|
||||
|
||||
template <typename T>
|
||||
std::vector<std::unique_ptr<Element>> make_safe_vector(T&& container) {
|
||||
std::vector<std::unique_ptr<Element>> result;
|
||||
|
||||
for (auto& el : container)
|
||||
result.emplace_back(std::move(el));
|
||||
|
||||
container.clear();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// std::vector<Element*> unsafe_vector;
|
||||
// unsafe_vector.emplace_back(new Element(0));
|
||||
// unsafe_vector.emplace_back(new Element(42));
|
||||
// unsafe_vector.emplace_back(new Element(900));
|
||||
|
||||
// auto safe_vector_1 = make_safe_vector(unsafe_vector);
|
||||
// unsafe_vector.push_back(new Element(99));
|
||||
|
||||
// auto safe_vector_2 = make_safe_vector(safe_vector_1);
|
||||
|
||||
// auto safe_vector_3 = make_safe_vector(std::list<Element*>{new Element(1), new Element(2), new Element(3)});
|
||||
|
||||
// std::cout << "unsafe_vector: " << std::endl;
|
||||
// for (auto& el : unsafe_vector) {
|
||||
// std::cout << el->value << std::endl;
|
||||
// delete el;
|
||||
// }
|
||||
|
||||
// std::cout << "safe_vector_1: " << std::endl;
|
||||
// for (auto& el : safe_vector_1)
|
||||
// std::cout << el->value << std::endl;
|
||||
|
||||
// std::cout << "safe_vector_2: " << std::endl;
|
||||
// for (auto& el : safe_vector_2)
|
||||
// std::cout << el->value << std::endl;
|
||||
|
||||
// std::cout << "safe_vector_3: " << std::endl;
|
||||
// for (auto& el : safe_vector_3)
|
||||
// std::cout << el->value << std::endl;
|
||||
// }
|
||||
|
||||
/*
|
||||
unsafe_vector:
|
||||
99
|
||||
safe_vector_1:
|
||||
safe_vector_2:
|
||||
0
|
||||
42
|
||||
900
|
||||
safe_vector_3:
|
||||
1
|
||||
2
|
||||
3
|
||||
*/
|
||||
@@ -0,0 +1,72 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
|
||||
int main() {
|
||||
std::map<int, std::map<char, int>> trans;
|
||||
std::set<int> accept_states;
|
||||
int init_state = -1;
|
||||
|
||||
std::ifstream Input("noMore.in");
|
||||
std::string str;
|
||||
while (std::getline(Input, str)) {
|
||||
if (str.empty()) break;
|
||||
if (str.find("[[") != std::string::npos) {
|
||||
int state;
|
||||
sscanf(str.c_str(), "[[%d]]", &state);
|
||||
accept_states.insert(state);
|
||||
if (init_state == -1) {
|
||||
init_state = state;
|
||||
}
|
||||
} else if (std::count(str.begin(), str.end(), '[') == 2) {
|
||||
int left_state, right_state;
|
||||
char symbol;
|
||||
sscanf(str.c_str(), "[%d] %c [%d]", &left_state, &symbol, &right_state);
|
||||
if (init_state == -1) {
|
||||
init_state = left_state;
|
||||
}
|
||||
trans[left_state][symbol] = right_state;
|
||||
} else {
|
||||
int state;
|
||||
sscanf(str.c_str(), "[%d]", &state);
|
||||
if (init_state == -1) {
|
||||
init_state = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int N;
|
||||
Input >> N;
|
||||
|
||||
std::vector<std::map<int, size_t>> dp(N + 1);
|
||||
dp[0][init_state] = 1;
|
||||
|
||||
for (int k = 1; k <= N; ++k) {
|
||||
for (auto& [state, count] : dp[k - 1]) {
|
||||
for (auto& [symbol, right_state] : trans[state]) {
|
||||
dp[k][right_state] += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t ans = 0;
|
||||
for (int k = 0; k <= N; ++k) {
|
||||
for (auto& [state, count] : dp[k]) {
|
||||
if (accept_states.count(state)) {
|
||||
ans += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream Output("noMore.out");
|
||||
Output << ans << std::endl;
|
||||
|
||||
Output.close();
|
||||
Input.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user