Skip to content

test

原始文件为 cpp 代码,本文是转换后的 Markdown 文件。

#include <string>
#include <vector>
#include <iostream>
#include <map>
#include <sstream>
#include <cstring>
#include <algorithm>

using namespace std;

class Bigint
{
    private:
        vector<int> number;
        bool positive;
        int base;
        unsigned int skip;
        static const int default_base=1000000000;

    public:
        //Constructors
        Bigint();
        Bigint(long long);
        Bigint(string);
        Bigint(const Bigint& b);

        //Adding
        Bigint operator+(Bigint const &) const;
        Bigint &operator+=(Bigint const &);
        Bigint operator+(long long const &) const;
        Bigint &operator+=(long long);

        //Subtraction
        Bigint operator-(Bigint const &) const;
        Bigint &operator-=(Bigint const &);

        //Allocation
        Bigint operator=(const long long &);
        Bigint operator=(string &);

        //Access
        int operator[](int const &);

        //Input&Output
        friend istream &operator>>(istream &, Bigint &);
        friend ostream &operator<<(ostream &, Bigint const &);

        //Helpers
        void clear();
        Bigint &abs();

        //Trivia
        int digits() const;
    private:
        int segment_length(int) const;
        Bigint pow(int const &, map<int, Bigint> &);
        int compare(Bigint const &) const; //0 a == b, -1 a < b, 1 a > b
};

Bigint abs(Bigint);
string to_string(Bigint const &);

//Constructor
Bigint::Bigint()
{
    positive = true;
    base = Bigint::default_base;
    skip = 0;
}
Bigint::Bigint(const Bigint &b)
    : number(b.number),
    positive(b.positive),
    base(b.base),
    skip(b.skip) { }
Bigint::Bigint(long long value)
{
    base = Bigint::default_base;
    skip = 0;
    if (value < 0) {
        positive = false;
        value *= -1;
    } else {
        positive = true;
    }

    while (value) {
        number.push_back((int) (value % base));
        value /= base;
    }
}

Bigint::Bigint(string stringInteger)
{
    int size = stringInteger.length();

    base = Bigint::default_base;
    skip = 0;
    positive = (stringInteger[0] != '-');

    while (true) {
        if (size <= 0) break;
        if (!positive && size <= 1) break;

        int length = 0;
        int num = 0;
        int prefix = 1;
        for (int i(size - 1); i >= 0 && i >= size - 9; --i) {
            if (stringInteger[i] < '0' || stringInteger[i] > '9') break;
            num += (stringInteger[i] - '0') * prefix;
            prefix *= 10;
            ++length;
        }
        number.push_back(num);
        size -= length;
    }
}

//Adding
Bigint Bigint::operator+(Bigint const &b) const
{
    Bigint c = *this;
    c += b;

    return c;
}

Bigint &Bigint::operator+=(Bigint const &b)
{
    if (!b.positive) {
        return *this -= b;
    }
    auto it1 = number.begin();
    auto it2 = b.number.begin();
    int sum = 0;
    while (it1 != number.end() || it2 != b.number.end()) {
        if (it1 != number.end()) {
            sum += *it1;
        } else {
            number.push_back(0);
            it1 = number.end()-1;
        }
        if (it2 != b.number.end()) {
            sum += *it2;
            ++it2;
        }
        *it1 = sum % base;
        ++it1;
        sum /= base;
    }
    if (sum) number.push_back(1);

    return *this;
}

Bigint Bigint::operator+(long long const &b) const
{
    Bigint c = *this;
    c += b;

    return c;
}

Bigint &Bigint::operator+=(long long b)
{
    vector<int>::iterator it = number.begin();
    if (skip > number.size()) {
        number.insert(number.end(), skip - number.size(), 0);
    }
    it += skip;
    bool initial_flag=true;
    while (b || initial_flag) {
        initial_flag=false;
        if (it != number.end()) {
            *it += b % base;
            b /= base;
            b += *it / base;
            *it %= base;
            ++it;
        } else {
            number.push_back(0);
            it = number.end() - 1;
        }
    }

    return *this;
}

//Subtraction
Bigint Bigint::operator-(Bigint const &b) const
{
    Bigint c = *this;
    c -= b;

    return c;
}

Bigint &Bigint::operator-=(Bigint const &b)
{
    vector<int>::iterator
        it1 = number.begin();
    vector<int>::const_iterator
        it2 = b.number.begin();
    int dif = 0;
    while (it1 != number.end() || it2 != b.number.end()) {
        if (it1 != number.end()) {
            dif += *it1;
            ++it1;
        }
        if (it2 != b.number.end()) {
            dif -= *it2;
            ++it2;
        }
        if (dif < 0) {
            *(it1 - 1) = dif + base;
            dif = -1;
        } else {
            *(it1 - 1) = dif % base;
            dif /= base;
        }
    }
    if (dif < 0) positive = false;

    if (number.size() > 1)
    {
        do
        {
            it1 = number.end() - 1;
            if (*it1 == 0) number.pop_back();
            else break;
        } while (number.size() > 1);
    }

    return *this;
}

//Allocation
Bigint Bigint::operator=(const long long &a)
{
    number.clear();
    long long t = a;
    do {
        number.push_back((int) (t % base));
        t /= base;
    } while (t != 0);

    return *this;
}

Bigint Bigint::operator=(string& stringInteger)
{
    int size = stringInteger.length();

    base = Bigint::default_base;
    skip = 0;
    positive = (stringInteger[0] != '-');

    while (true) {
        if (size <= 0) break;
        if (!positive && size <= 1) break;

        int length = 0;
        int num = 0;
        int prefix = 1;
        for (int i(size - 1); i >= 0 && i >= size - 9; --i) {
            if (stringInteger[i] < '0' || stringInteger[i] > '9') break;
            num += (stringInteger[i] - '0') * prefix;
            prefix *= 10;
            ++length;
        }
        number.push_back(num);
        size -= length;
    }
    return *this;
}

//Access
int Bigint::operator[](int const &b)
{
    return to_string(*this)[b] - '0';
}

//Trivia
int Bigint::digits() const
{
    int segments = number.size();

    if (segments == 0) return 0;

    int digits = 9 * (segments - 1);
    digits += segment_length(number.back());

    return digits;
}

//Helpers
void Bigint::clear()
{
    number.clear();
    positive = true;
    skip = 0;
}

Bigint &Bigint::abs()
{
    positive = true;

    return *this;
}

//Input&Output
ostream &operator<<(ostream &out, Bigint const &a)
{
    if (!a.number.size()) return out << 0;
    int i = a.number.size() - 1;
    for (; i>=0 && a.number[i] == 0; --i);

    if (i == -1) return out << 0;
    if (!a.positive) out << '-';

    vector<int>::const_reverse_iterator it = a.number.rbegin() + (a.number.size() - i - 1);

    out << *it++;
    for (; it != a.number.rend(); ++it) {
        for (int i(0), len = a.segment_length(*it); i < 9 - len; ++i) out << '0';
        if (*it) out << *it;
    }

    return out;
}

istream &operator>>(istream &in, Bigint &a)
{
    string str;
    in >> str;

    a = str;

    return in;
}

int Bigint::segment_length(int segment) const
{
    int length = 0;
    while (segment) {
        segment /= 10;
        ++length;
    }

    return length;
}

Bigint abs(Bigint value)
{
    return value.abs();
}

string to_string(Bigint const &value)
{
    ostringstream stream;
    stream << value;

    return stream.str();
}

struct Node
{
    Node* child[10];
    bool have_value;
    int value;

    Node() { have_value = false;  for(int i = 0; i < 10; ++i) child[i] = NULL; }
    void setvalue(int index) { value = index; have_value = true; }
};

Node* root;

const int maxn = 100005;
int tree[40][10];

void init();
void build(string str, int index);
int query(string str);

int main()
{
    // freopen("in.txt", "r", stdin);
    init();

    Bigint a = 0, b = 1;
    for(int i = 0; i < 100000; ++i)
    {
        build(to_string(b), i);
        Bigint tmp = b;
        // b = a + b;
        if(to_string(tmp).size() > 50)
        {
            b = to_string(a + b).substr(0, 50);
            a = to_string(tmp).substr(0,50);
        }else
        {
            b = to_string(a + b).substr(0, 51);
            a = tmp;
        }
    }

    int T; cin >> T;
    for(int i = 1; i <= T; ++i)
    {
        string str; cin >> str;
        printf("Case #%d: %d\n", i, query(str));
    }
}

void init()
{
    root = new Node();
}

void build(string str, int index)
{
    Node* cur_node = root;
    for(int i = 0; i < str.length(); ++i)
    {
        int num = str[i] - '0';
        if(!cur_node->child[num])
        {
            cur_node->child[num] = new Node();
            cur_node->child[num]->setvalue(index);
        }
        cur_node = cur_node->child[num];
    }
}

int query(string str)
{
    Node* cur_node = root;
    for(int i = 0; i < str.length(); ++i)
    {
        int num = str[i] - '0';
        if(!cur_node->child[num])
        {
            return -1;
        }
        cur_node = cur_node->child[num];
    }
    return cur_node->value;
}