Часто используемые фрагменты

Материал из Олимпиадное программирование в УлГТУ
Перейти к навигации Перейти к поиску

Split и join

vector<string> split(string &line) {
    vector<string> words;
    string word;
    for (char c : line) {
        if (c != ' ') {
            word += c;
        } else if (!word.empty()) {
            words.push_back(word);
            word.clear();
        }
    }
    if (!word.empty())
        words.push_back(word);
    return words;
}
 
string join(vector<string> &words) {
    string line;
    for (int i = 0; i < words.size(); i++)
        line += words[i] + (i + 1 < words.size() ? " " : "");
    return line;
}
vector<string> split(string &line, const string &separators) {
    vector<string> words;
    string word;
    for (char c : line) {
        if (separators.find(c) == -1) {
            word += c;
        } else if (!word.empty()) {
            words.push_back(word);
            word.clear();
        }
    }
    if (!word.empty())
        words.push_back(word);
    return words;
}
 
string join(vector<string> &words, const string &separator) {
    string line;
    for (int i = 0; i < words.size(); i++)
        line += words[i] + (i + 1 < words.size() ? separator : "");
    return line;
}

Сумма цифр

int digitSum(int n) {
    int sum = 0;
    while (n) {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}
 
int ones(int n) {
    int res = 0;
    while (n) {
        res++;
        n &= n - 1;
    }
    return res;
}

Перевод систем счисления

long long toDec(string s, int base) {
    static const string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    long long res = 0;
    for (char c : s)
        res = res * base + DIGITS.find(c);
    return res;
}
 
string fromDec(long long n, int base) {
    static const string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string res;
    while (n >= base) {
        res += DIGITS[n % base];
        n /= base;
    }
    res += DIGITS[n];
    reverse(res.begin(), res.end());
    return res;
}

Римская система счисления

string toRoman(int n) {
    static const vector<pair<string, int>> CODES = {
        {"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400},
        {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40},
        {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}
    };
    
    string res;
    for (auto &[code, value] : CODES) {
        while (n >= value) {
            n -= value;
            res += code;
        }
    }
    return res;        
}
 
int fromRoman(string &s) {
    static const vector<pair<string, int>> CODES = {
        {"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400},
        {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40},
        {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}
    };
    
    int pos = 0, res = 0;
    for (auto &[code, value] : CODES) {
        while (s.substr(pos, code.size()) == code) {
            pos += code.size();
            res += value;
        }
    }
    return res;
}

Задача Иосифа

int size, step;
cin >> size >> step;

vector<int> a(size);
iota(a.begin(), a.end(), 1);

int pos = 0;
while (!a.empty()) {
    pos = (pos + step - 1) % a.size();
    cout << a[pos] << " ";
    a.erase(a.begin() + pos);
}

Даты

struct Date {
    int day, month, year, dayOfWeek;

    bool isLeap(int year) {
        return year % 400 == 0 || year % 100 && year % 4 == 0;
    }

    int daysInMonth(int month, int year) {
        vector<int> days = { 0, 31, 28 + isLeap(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        return days[month];
    }

    Date &operator++(int) {
        day++;
        if (day > daysInMonth(month, year)) {
            day = 1;
            month++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }
        dayOfWeek = (dayOfWeek + 1) % 7;
        return *this;
    }

    friend ostream &operator << (ostream &out, Date &date) {
        static vector<string> names = {
            "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
        };
        out << names[date.dayOfWeek] << ", ";
        out << setw(2) << setfill('0') << date.day << ".";
        out << setw(2) << setfill('0') << date.month;
        return out;
    }
};

Время

int readTime() {
    int hours, minutes;
    char colon;
    cin >> hours >> colon >> minutes;

    return hours * 60 + minutes;
}
 
void writeTime(int time) {
    cout << setw(2) << setfill('0') << time / 60 << ":";
    cout << setw(2) << setfill('0') << time % 60;
}

Дроби

struct Fraction {
    long long num, den;

    Fraction(long long n = 0, long long d = 1) : num(n), den(d) {
        long long g = gcd(num, den);
        num /= g;
        den /= g;

        if (den < 0) {
            num = -num;
            den = -den;
        }
    }

    Fraction operator + (const Fraction &that) const {
        return { num * that.den + that.num * den, den * that.den };
    }

    Fraction operator - (const Fraction &that) const {
        return { num * that.den - that.num * den, den * that.den };
    }

    Fraction operator * (const Fraction &that) const {
        return { num * that.num, den * that.den };
    }

    Fraction operator / (const Fraction &that) const {
        return { num * that.den, den * that.num };
    }

    friend istream &operator >> (istream &in, Fraction &f) {
        long long num, den = 1;
        in >> num;
        if (in.peek() == '/') {
            in.ignore();
            in >> den;
        }
        f = { num, den };
        return in;
    }

    friend ostream &operator << (ostream &out, const Fraction &f) {
        out << f.num;
        if (f.den != 1)
            out << "/" << f.den;
        return out;
    }
};