模板2 (Past)

10184602226 edited 3 年,6 月前

This is a past version of blog 模板2

include

include

include

include

include

include

include

include

include

include

include

include

include

include

using namespace std;
using u64 = uint64_t;
const long double PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446;

//****模板BEGIN*****
class StringUtil {
public:
//用c来分割s,返回分割后的一个个字符串
vector split(string s, char c);
//去除一个字符串前后的空格
string trim(string s);
//把一个字符串转换为字符vector
vector toCharVector(string s);
//把一个字符vector转换为字符串
string vectorToString(vector v);
//专门用来分割空格
vector 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
vector> initMatrix(int m, int n, T dft);

//快速幂,计算kBase^kExp再对kMod取余后的结果
template
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 StringUtil::split(string s, char c) {
vector 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 StringUtil::toCharVector(string s) {
vector res;
for (int i = 0;i < s.size();i++) {
res.push_back(s[i]);
}
return res;
}
string StringUtil::vectorToString(vector v) {
string res = “”;
for (char c : v) {
res += c;
}
return res;
}
vector StringUtil::splitBlank(string s) {
vector 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 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 numList;
for (int i = ssize - 1;i >= 0;i–) {
stack 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 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 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
vector> initMatrix(int m, int n, T dft) {
vector> matrix;
vector 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
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*******