模板2 (Past)

10184602226 edited 3 年,9 月前

This is a past version of blog 模板2

#include "pch.h"
#include <iostream>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <string>
#include <functional>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <string.h>
using namespace std;
using u64 = uint64_t;
const long double PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446;


//****************************模板BEGIN***********************************
class StringUtil {
public:
    //用c来分割s,返回分割后的一个个字符串
    vector<string> split(string s, char c);
    //去除一个字符串前后的空格
    string trim(string s);
    //把一个字符串转换为字符vector
    vector<char> toCharVector(string s);
    //把一个字符vector转换为字符串
    string vectorToString(vector<char> v);
    //专门用来分割空格
    vector<string> splitBlank(string s);
};

class BigNumUtil {
public:
    //两个超大正整数的加法
    string bigDecimalAdd(string num1, string num2);
    //两个超大正整数的乘法
    string bigDecimalMultiply(string num1, string num2);
    //两个超大正整数的减法,注意需要num1≥num2
    string bigDecimalMinus(string num1, string num2);
    //两个超大正整数的除法,目前分子小于分母的没问题,如果除不尽,cir_start和cir_end指出了循环节的首尾
    string bigDecimalDivide(string up, string down, int& cir_start, int& cir_end);
    //两个超大正整数比较大小
    int bigDecimalCompare(string num1, string num2);
};

class MathUtil {
public:
    //最大公约数,辗转相除法
    int getLCM(int a, int b);
    //最小公倍数
    int getGCD(int a, int b);
};

//初始化一个m*n的二维数组,使用dtf填充,返回的vector可以当作数组一样使用
template<typename T>
vector<vector<T>> initMatrix(int m, int n, T dft);

//快速幂,计算kBase^kExp再对kMod取余后的结果
template <typename UInt>
UInt fastPow(UInt const kBase, UInt const kExp, UInt const kMod);

//****************************模板END*************************************

int main() {
    int T;
    cin >> T;
    for (int t = 0;t < T;t++) {

        cout << "case #" << t << ":" << endl;

    }
}










//****************************模板BEGIN***********************************
vector<string> StringUtil::split(string s, char c) {
    vector<string> result;
    int len = s.size();
    string temp = "";
    for (int i = 0;i < len;i++) {
        if (s[i] != c) {
            temp += s[i];
        }
        else {
            result.push_back(temp);
            temp = "";
        }
    }
    if (temp != ""){
        result.push_back(temp);
    }
    return result;
}
string StringUtil::trim(string s) {
    string res = "";
    int ptr = 0;
    while (s[ptr] == ' ') {
        ptr++;
    }
    while (ptr != s.size()) {
        res += s[ptr++];
    }
    auto it = res.end() - 1;
    while (*it == ' ') {
        res.erase(it);
        it--;
    }
    return res;
}
vector<char> StringUtil::toCharVector(string s) {
    vector<char> res;
    for (int i = 0;i < s.size();i++) {
        res.push_back(s[i]);
    }
    return res;
}
string StringUtil::vectorToString(vector<char> v) {
    string res = "";
    for (char c : v) {
        res += c;
    }
    return res;
}
vector<string> StringUtil::splitBlank(string s) {
    vector<string> result;
    s = StringUtil().trim(s);
    int ptr = 0;
    bool processChar = true;
    string temp = "";
    while (true) {
        if (processChar) {
            if (s[ptr] != ' ') {
                temp += s[ptr];
                ptr++;
            }
            else {
                result.push_back(temp);
                temp = "";
                processChar = false;
            }
        }
        else {
            if (s[ptr] != ' ') {
                temp += s[ptr];
                processChar = true;
            }
            ptr++;
        }
        if (ptr == s.size()) {
            if (temp != "") {
                result.push_back(temp);
            }
            break;
        }
    }
    return result;
}
string BigNumUtil::bigDecimalAdd(string num1, string num2) {
    string s = num2;
    string l = num1;
    if (num1.size() <= num2.size()) {
        s = num1;
        l = num2;
    }
    int ssize = s.size();
    int lsize = l.size();
    int sptr = ssize - 1;
    int lptr = lsize - 1;
    vector<int> v;
    int up = 0;
    while (true) {
        int digit1 = s[sptr--] - '0';
        int digit2 = l[lptr--] - '0';
        int cal = digit1 + digit2 + up;
        if (cal >= 10) {
            up = 1;
            cal -= 10;
        }
        else {
            up = 0;
        }
        v.push_back(cal);
        if (sptr == -1) {
            while (lptr != -1) {
                cal = l[lptr--] - '0' + up;
                if (cal >= 10) {
                    up = 1;
                    cal -= 10;
                }
                else {
                    up = 0;
                }
                v.push_back(cal);
            }
            if (up == 1) {
                v.push_back(1);
            }
            break;
        }
    }
    string res = "";
    for (int i = v.size() - 1;i >= 0;i--) {
        res += (v[i] + '0');
    }
    return res;
}
string BigNumUtil::bigDecimalMultiply(string num1, string num2) {
    string s = num2;
    string l = num1;
    if (num1.size() <= num2.size()) {
        s = num1;
        l = num2;
    }
    int ssize = s.size();
    int lsize = l.size();
    vector<string> numList;
    for (int i = ssize - 1;i >= 0;i--) {
        stack<char> temp;
        int digit1 = s[i] - '0';
        int up = 0;
        for (int j = lsize - 1;j >= 0;j--) {
            int digit2 = l[j] - '0';
            int cal = digit1 * digit2 + up;
            if (cal >= 10) {
                up = cal / 10;
                cal = cal % 10;
            }
            else {
                up = 0;
            }
            temp.push(cal + '0');
            if (j == 0 && up != 0) {
                temp.push(up + '0');
            }
        }
        string res = "";
        while (!temp.empty()) {
            res += temp.top();
            temp.pop();
        }
        //补上0,比如40*123时,那个0得在这里补上
        for (int j = 0;j < ssize - 1 - i;j++) {
            res += "0";
        }
        numList.push_back(res);
    }
    string res = "0";
    for (int i = 0;i < numList.size();i++) {
        res = BigNumUtil::bigDecimalAdd(res, numList[i]);
    }
    return res;
}
string BigNumUtil::bigDecimalMinus(string num1, string num2) {
    if (num1 == num2) {
        return "0";
    }
    int size1 = num1.size();
    int size2 = num2.size();
    int ptr1 = size1 - 1;
    int ptr2 = size2 - 1;
    int borrow = 0;
    stack<char> stk;
    while (true) {
        int cal = num1[ptr1--] - '0' - (num2[ptr2--] - '0') - borrow;
        if (cal < 0) {
            borrow = 1;
            cal += 10;
        }
        else {
            borrow = 0;
        }
        stk.push(cal + '0');
        if (ptr2 == -1) {
            while (ptr1 != -1) {
                int cal = num1[ptr1--] - '0' - borrow;
                if (cal < 0) {
                    borrow = 1;
                    cal += 10;
                }
                else {
                    borrow = 0;
                }
                stk.push(cal + '0');
            }
            while (stk.top() == '0') {
                stk.pop();
            }
            break;
        }
    }
    string res = "";
    while (!stk.empty()) {
        res += stk.top();
        stk.pop();
    }
    return res;
}
string BigNumUtil::bigDecimalDivide(string up, string down, int& cir_start, int& cir_end) {
    if (up == "0") {
        return "0.0";
    }
    //准备好分母的所有倍数,后续可以直接取用
    vector<string> timesOfDown;
    timesOfDown.push_back("0");
    timesOfDown.push_back(down);
    for (int i = 2;i <= 10;i++) {
        timesOfDown.push_back(bigDecimalMultiply(string(1, i + '0'), down));
    }
    int ptr = 0;
    int upSize = up.size();
    //被减数
    string currentString = "";
    string res = "";
    //可能会除不尽,当count到一定地步就别继续了
    int count = 0;
    while (true) {
        count++;
        bool canStop = false;
        if (ptr < upSize) {
            currentString += up[ptr];
        }
        else if (ptr == upSize) {
            res += '.';
            currentString += '0';
        }
        else {
            currentString += '0';
        }
        ptr++;
        for (int i = 1;i < 11;i++) {
            if (bigDecimalCompare(timesOfDown[i], currentString) == 1) {
                //减数
                string minu = timesOfDown[i - 1];
                //商
                res += (i - 1 + '0');
                //作差
                currentString = bigDecimalMinus(currentString, minu);
                //余数为0,说明除尽了
                if (currentString == "0") {
                    canStop = true;
                }

                break;
            }
        }
        if (canStop||count==200) {
            break;
        }
    }
    auto it = res.begin();
    while (*it == '0') {
        res.erase(it);
    }
    if (*it == '.') {
        res.insert(it, '0');
    }
    //如果是除不尽的,找出循环节
    if (count == 200) {
        for (int i = 2;i < 100;i++) {
            for (int j = i;j < 100;j++) {
                string cir = res.substr(i, j-i+1);
                int cir_ptr = 0;
                int ptr = j + 1;
                while (true) {
                    if (cir[cir_ptr] == res[ptr]) {
                        cir_ptr = (cir_ptr + 1) % cir.size();
                        ptr++;
                        if (ptr == res.size()) {
                            cir_start = i-1;
                            cir_end = j-1;
                            res = res.substr(0, j+1);
                            return res;
                        }
                    }
                    else {
                        break;
                    }
                }
            }
        }
    }
    return res;
}
int BigNumUtil::bigDecimalCompare(string num1, string num2) {
    if (num1.size() > num2.size()) {
        return 1;
    }
    if (num1.size() < num2.size()) {
        return -1;
    }
    int ptr = 0;
    while (ptr != num1.size()) {
        if (num1[ptr] > num2[ptr]) {
            return 1;
        }
        if (num1[ptr] < num2[ptr]) {
            return -1;
        }
        ptr++;
    }
    return 0;

}
template<typename T>
vector<vector<T>> initMatrix(int m, int n, T dft) {
    vector<vector<T>> matrix;
    vector<T> row;
    row.resize(n,dft);
    matrix.resize(m, row);
    return matrix;
}
int MathUtil::getLCM(int a, int b) {
    int max = (a > b ? a : b);
    int min = (a < b ? a : b);
    int res = max % min;
    while (res) {
        max = min;
        min = res;
        res = max % min;
    }
    return min;
}
int MathUtil::getGCD(int a, int b) {
    return a * b / getLCM(a, b);
}
template <typename UInt> 
UInt fastPow(UInt const kBase, UInt const kExp, UInt const kMod) {
    UInt ret = 1;
    for (UInt i = kExp, base = kBase % kMod; i; i >>= 1) {
        if (i & 1) {
            ret = ret * base % kMod;
        }
        base = base * base % kMod;
    }
    return ret;
}
//****************************模板END*************************************