ACM-ICPC 2018 焦作赛区网络预赛J题 Participate in E-sports

Posted songorz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM-ICPC 2018 焦作赛区网络预赛J题 Participate in E-sports相关的知识,希望对你有一定的参考价值。

Jessie and Justin want to participate in e-sports. E-sports contain many games, but they don‘t know which one to choose, so they use a way to make decisions.

They have several boxes of candies, and there are ii candies in the i^{th}ith box, each candy is wrapped in a piece of candy paper. Jessie opens the candy boxes in turn from the first box. Every time a box is opened, Jessie will take out all the candies inside, finish it, and hand all the candy papers to Justin.

When Jessie takes out the candies in the N^{th}Nth box and hasn‘t eaten yet, if the amount of candies in Jessie‘s hand and the amount of candy papers in Justin‘s hand are both perfect square numbers, they will choose Arena of Valor. If only the amount of candies in Jessie‘s hand is a perfect square number, they will choose Hearth Stone. If only the amount of candy papers in Justin‘s hand is a perfect square number, they will choose Clash Royale. Otherwise they will choose League of Legends.

Now tell you the value of NN, please judge which game they will choose.

Input

The first line contains an integer T(1 le T le 800)T(1T800) , which is the number of test cases.

Each test case contains one line with a single integer: N(1 le N le 10^{200})N(1N10200) .

Output

For each test case, output one line containing the answer.

样例输入

4
1
2
3
4

样例输出

Arena of Valor
Clash Royale
League of Legends
Hearth Stone

题目来源

ACM-ICPC 2018 焦作赛区网络预赛

题解:判断N和N*(N-1)/2,由于N范围是1~10^200.数据太大,故用大数运算;

下面附上大数运算模板:

参考代码:

#include <bits/stdc++.h>
using namespace std;
// base and base_digits must be consistent
constexpr int base = 1000000000;
constexpr int base_digits = 9;
struct bigint{
    vector<int> z;
    int sign;
    bigint() : sign(1) {}
    bigint(long long v) { *this = v; }
    bigint& operator=(long long v)
    {
        sign = v < 0 ? -1 : 1;
        v*=sign;
        z.clear();
        for(; v > 0; v = v / base) z.push_back((int)(v % base));
        return *this;
    }

    bigint(const string& s) { read(s); }

    bigint& operator+=(const bigint& other)
    {
        if (sign == other.sign)
        {
            for (int i = 0, carry = 0; i < other.z.size() || carry; ++i)
            {
                if (i == z.size())
                    z.push_back(0);
                z[i] += carry + (i < other.z.size() ? other.z[i] : 0);
                carry = z[i] >= base;
                if (carry)
                    z[i] -= base;
            }
        }
        else if (other != 0 /* prevent infinite loop */)
        {
            *this -= -other;
        }
        return *this;
    }

    friend bigint operator+(bigint a, const bigint& b)
    {
        return a += b;
    }

    bigint& operator-=(const bigint& other)
    {
        if (sign == other.sign)
        {
            if (sign == 1 && *this >= other || sign == -1 && *this <= other)
            {
                for (int i = 0, carry = 0; i < other.z.size() || carry; ++i)
                {
                    z[i] -= carry + (i < other.z.size() ? other.z[i] : 0);
                    carry = z[i] < 0;
                    if (carry)
                        z[i] += base;
                }
                trim();
            }
            else
            {
                *this = other - *this;
                this->sign = -this->sign;
            }
        }
        else
        {
            *this += -other;
        }
        return *this;
    }

    friend bigint operator-(bigint a, const bigint& b)
    {
        return a -= b;
    }

    bigint& operator*=(int v)
    {
        if (v < 0)
            sign = -sign, v = -v;
        for (int i = 0, carry = 0; i < z.size() || carry; ++i)
        {
            if (i == z.size())
                z.push_back(0);
            long long cur = (long long)z[i] * v + carry;
            carry = (int)(cur / base);
            z[i] = (int)(cur % base);
        }
        trim();
        return *this;
    }

    bigint operator*(int v) const
    {
        return bigint(*this) *= v;
    }

    friend pair<bigint, bigint> divmod(const bigint& a1, const bigint& b1)
    {
        int norm = base / (b1.z.back() + 1);
        bigint a = a1.abs() * norm;
        bigint b = b1.abs() * norm;
        bigint q, r;
        q.z.resize(a.z.size());

        for (int i = (int)a.z.size() - 1; i >= 0; i--)
        {
            r *= base;
            r += a.z[i];
            int s1 = b.z.size() < r.z.size() ? r.z[b.z.size()] : 0;
            int s2 = b.z.size() - 1 < r.z.size() ? r.z[b.z.size() - 1] : 0;
            int d = (int)(((long long)s1 * base + s2) / b.z.back());
            r -= b * d;
            while (r < 0)
                r += b, --d;
            q.z[i] = d;
        }

        q.sign = a1.sign * b1.sign;
        r.sign = a1.sign;
        q.trim();
        r.trim();
        return {q, r / norm};
    }

    friend bigint sqrt(const bigint& a1)
    {
        bigint a = a1;
        while (a.z.empty() || a.z.size() % 2 == 1)
            a.z.push_back(0);

        int n = a.z.size();

        int firstDigit = (int)::sqrt((double)a.z[n - 1] * base + a.z[n - 2]);
        int norm = base / (firstDigit + 1);
        a *= norm;
        a *= norm;
        while (a.z.empty() || a.z.size() % 2 == 1)
            a.z.push_back(0);

        bigint r = (long long)a.z[n - 1] * base + a.z[n - 2];
        firstDigit = (int)::sqrt((double)a.z[n - 1] * base + a.z[n - 2]);
        int q = firstDigit;
        bigint res;

        for (int j = n / 2 - 1; j >= 0; j--)
        {
            for(;;--q)
            {
                bigint r1=(r-(res*2*base+q)*q)*base*base+(j>0?(long long)a.z[2*j-1]*base+a.z[2*j-2]:0);
                if(r1>= 0)
                {
                    r = r1;
                    break;
                }
            }
            res *= base; res += q;
            if(j > 0)
            {
                int d1 = res.z.size() + 2 < r.z.size() ? r.z[res.z.size() + 2] : 0;
                int d2 = res.z.size() + 1 < r.z.size() ? r.z[res.z.size() + 1] : 0;
                int d3 = res.z.size() < r.z.size() ? r.z[res.z.size()]:0;
                q = (int)(((long long)d1*base*base+(long long)d2*base+d3)/(firstDigit*2));
            }
        }

        res.trim();
        return res / norm;
    }

    bigint operator/(const bigint& v) const
    {
        return divmod(*this, v).first;
    }

    bigint operator%(const bigint& v) const
    {
        return divmod(*this, v).second;
    }

    bigint& operator/=(int v)
    {
        if(v<0) sign=-sign,v=-v;
        for (int i = (int)z.size() - 1, rem = 0; i >= 0; --i)
        {
            long long cur = z[i] + rem * (long long)base;
            z[i] = (int)(cur / v);
            rem = (int)(cur % v);
        }
        trim();
        return *this;
    }

    bigint operator/(int v) const
    {
        return bigint(*this) /= v;
    }

    int operator%(int v) const
    {
        if(v<0) v=-v;
        int m=0;
        for(int i=(int)z.size()-1;i>=0;--i) m=(int)((z[i]+m*(long long)base)%v);
        return m * sign;
    }

    bigint& operator*=(const bigint& v)
    {
        *this = *this * v;
        return *this;
    }

    bigint& operator/=(const bigint& v)
    {
        *this = *this / v;
        return *this;
    }

    bool operator<(const bigint& v) const
    {
        if(sign!=v.sign) return sign < v.sign;
        if(z.size()!=v.z.size()) return z.size()*sign<v.z.size()*v.sign;
        for(int i = (int)z.size() - 1; i >= 0; i--)
            if(z[i] != v.z[i])  return z[i] * sign < v.z[i] * sign;
        return false;
    }

    bool operator>(const bigint& v) const { return v < *this; }
    bool operator<=(const bigint& v) const { return !(v < *this); }
    bool operator>=(const bigint& v) const { return !(*this < v); }
    bool operator==(const bigint& v) const { return !(*this < v) && !(v < *this); }
    bool operator!=(const bigint& v) const { return *this < v || v < *this; }

    void trim()
    {
        while(!z.empty() && z.back() == 0) z.pop_back();
        if(z.empty()) sign = 1;
    }

    bool isZero() const { return z.empty(); }

    friend bigint operator-(bigint v)
    {
        if(!v.z.empty()) v.sign = -v.sign;
        return v;
    }

    bigint abs() const
    {
        return sign == 1 ? *this : -*this;
    }

    long long longValue() const
    {
        long long res = 0;
        for(int i = (int)z.size() - 1; i >= 0; i--) res = res * base + z[i];
        return res * sign;
    }

    friend bigint gcd(const bigint& a, const bigint& b)
    {
        return b.isZero() ? a : gcd(b, a % b);
    }

    friend bigint lcm(const bigint& a, const bigint& b)
    {
        return a / gcd(a, b) * b;
    }

    void read(const string& s)
    {
        sign = 1;
        z.clear();
        int pos = 0;
        while (pos < s.size() && (s[pos] == ‘-‘ || s[pos] == ‘+‘))
        {
            if(s[pos] == ‘-‘) sign = -sign;
            ++pos;
        }
        for (int i = (int)s.size() - 1; i >= pos; i -= base_digits)
        {
            int x = 0;
            for(int j = max(pos, i - base_digits + 1); j <= i; j++) x = x * 10 + s[j] - ‘0‘;
            z.push_back(x);
        }
        trim();
    }

    friend istream& operator>>(istream& stream, bigint& v)
    {
        string s;
        stream >> s;
        v.read(s);
        return stream;
    }

    friend ostream& operator<<(ostream& stream, const bigint& v)
    {
        if(v.sign == -1) stream << ‘-‘;
        stream << (v.z.empty() ? 0 : v.z.back());
        for(int i = (int)v.z.size() - 2; i >= 0; --i)
            stream << setw(base_digits) << setfill(‘0‘) << v.z[i];
        return stream;
    }

    static vector<int> convert_base(const vector<int>& a, int old_digits, int new_digits)
    {
        vector<long long> p(max(old_digits, new_digits) + 1);
        p[0] = 1;
        for (int i = 1; i < p.size(); i++)
            p[i] = p[i - 1] * 10;
        vector<int> res;
        long long cur = 0;
        int cur_digits = 0;
        for (int v : a)
        {
            cur += v * p[cur_digits];
            cur_digits += old_digits;
            while (cur_digits >= new_digits)
            {
                res.push_back(int(cur % p[new_digits]));
                cur /= p[new_digits];
                cur_digits -= new_digits;
            }
        }
        res.push_back((int)cur);
        while (!res.empty() && res.back() == 0)
            res.pop_back();
        return res;
    }

    typedef vector<long long> vll;
    static vll karatsubaMultiply(const vll& a, const vll& b)
    {
        int n=a.size();
        vll res(n + n);
        if(n <= 32)
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    res[i + j] += a[i] * b[j];
            return res;
        }

        int k = n >> 1;
        vll a1(a.begin(), a.begin() + k);
        vll a2(a.begin() + k, a.end());
        vll b1(b.begin(), b.begin() + k);
        vll b2(b.begin() + k, b.end());
        vll a1b1 = karatsubaMultiply(a1, b1);
        vll a2b2 = karatsubaMultiply(a2, b2);
        for(int i=0;i<k;i++) a2[i]+=a1[i];
        for(int i=0;i<k;i++) b2[i]+=b1[i];

        vll r = karatsubaMultiply(a2, b2);
        for(int i=0;i<a1b1.size();i++) r[i]-=a1b1[i];
        for(int i=0;i<a2b2.size();i++) r[i]-=a2b2[i];
        for(int i=0;i<r.size();i++) res[i+k]+=r[i];
        for(int i=0;i<a1b1.size();i++) res[i]+=a1b1[i];
        for(int i = 0;i<a2b2.size();i++) res[i+n]+=a2b2[i];
        return res;
    }

    bigint operator*(const bigint& v) const
    {
        vector<int> a6=convert_base(this->z,base_digits,6);
        vector<int> b6=convert_base(v.z,base_digits,6);
        vll a(a6.begin(),a6.end());
        vll b(b6.begin(),b6.end());
        while(a.size()<b.size()) a.push_back(0);
        while(b.size()<a.size()) b.push_back(0);
        while(a.size()&(a.size()-1)) a.push_back(0),b.push_back(0);
        vll c=karatsubaMultiply(a, b);
        bigint res;
        res.sign = sign * v.sign;
        for (int i = 0, carry = 0; i < c.size(); i++)
        {
            long long cur = c[i] + carry;
            res.z.push_back((int)(cur % 1000000));
            carry = (int)(cur / 1000000);
        }
        res.z = convert_base(res.z, 6, base_digits);
        res.trim();
        return res;
    }
};

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    bigint a, b, sa, sb;
    int T; cin >> T;
    while(T--)
    {
        cin >> b;
        a = b * (b - 1) / 2;
        sa = sqrt(a); sb = sqrt(b);
        bool f1 = (sa * sa) == a;
        bool f2 = (sb * sb) == b;
        if(f1&&f2) cout<<"Arena of Valor"<<endl;
        else if(f1 && !f2) cout<<"Clash Royale"<<endl;
        else if(!f1 && !f2) cout<<"League of Legends"<<endl;
        else if (!f1 && f2) cout<<"Hearth Stone"<<endl;
    }
    return 0;
}

  

以上是关于ACM-ICPC 2018 焦作赛区网络预赛J题 Participate in E-sports的主要内容,如果未能解决你的问题,请参考以下文章

ACM-ICPC 2018 焦作赛区网络预赛 G题 Give Candies

ACM-ICPC 2018 焦作赛区网络预赛 L 题 Poor God Water

ACM-ICPC 2018 焦作赛区网络预赛 Solution

ACM-ICPC 2018 焦作赛区网络预赛 I题(滑稽)

ACM-ICPC 2018 焦作赛区网络预赛 K题 Transport Ship

ACM-ICPC 2018 焦作赛区网络预赛 Transport Ship