大数开方 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}i
th
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}N
th
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(1≤T≤800) , 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(1≤N≤10
200
) .
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
题目来源
先看看 大数开放
手算开方的原理是利用(10a + b)(10a + b)= 100 a^2 + 20ab + b^2,
先把一个大整数从最低位开始分解成两个一节的。 eg. 12,34,56,78,90
①首先先看最前面一节,小于等于12的一个最大的平方数是9,先取a = 3,此时余数是3,将下一节加入余数,得到r = 3,34
②接下来求最大的 b 使得 20ab + b^2 <= 334, 这里先将a 代进去,得到b = 5,此时余数是 9
③此时需要将a 用 10a + b 取代,所以这时候a = 35,讲下一节加入r ,r = 9,56
接着不断重复重复②和③这两个步骤。
这边顺便再写两步,此时再去找最大的 b 使得 20ab + b^2 <= 956,将a = 35代入,求得 b = 1, 然后r = 2,55,然后 a = 351,将后一节加入r, r = 2,55,78.。。。。。
大数开放解决后 就直接上代码了
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int MOD = 2;
const int D_MOD = 100;
const int MAXN = 400 + 5;
int n;
char str[MAXN];
int getInt(char *str, int len)
{
int res = 0;
for(int i = 0; i < len; ++ i)
res = res * 10 + (str[i] - '0');
return res;
}
class BigNumber
{
public:
int intLen;
int decimal[MAXN];
BigNumber()
{
this->intLen = 1;
memset(this->decimal, 0, sizeof(this->decimal));
}
BigNumber(char *str)
{
//初始化
this->intLen = 1;
int intLen = (int)strlen(str);
this->intLen = (intLen + MOD - 1) / MOD;
memset(this->decimal, 0, sizeof(this->decimal));
if(intLen & 1)
{
this->decimal[this->intLen - 1] = getInt(str, 1);
++str;
}
else
{
this->decimal[this->intLen - 1] = getInt(str, 2);
str += 2;
}
for(int i = this->intLen - 2; i >= 0; -- i, str += 2)
this->decimal[i] = getInt(str, 2);
}
bool operator > (const BigNumber &x) const
{
if(this->intLen == x.intLen)
for(int i = x.intLen - 1; i >= 0; -- i)
if(this->decimal[i] != x.decimal[i])
return this->decimal[i] > x.decimal[i];
return this->intLen > x.intLen;
}
bool operator == (const BigNumber &x) const
{
if(this->intLen == x.intLen)
{
for(int i = 0; i < x.intLen; ++ i)
if(this->decimal[i] != x.decimal[i])
return false;
return true;
}
return (this->intLen == x.intLen);
}
//加上一个小于D_MOD的数
BigNumber operator + (int x) const
{
int tt;
BigNumber bg;
bg.intLen = this->intLen;
for(int i = 0; i < this->intLen; ++ i)
{
tt = this->decimal[i] + x;
bg.decimal[i] = tt % D_MOD;
x = tt / D_MOD;
}
if(x)
bg.decimal[bg.intLen++] = x;
return bg;
}
//保证了差为正数时才可调用
BigNumber operator - (const BigNumber & x) const
{
BigNumber bg;
bg.intLen = this->intLen;
for(int i = 0; i < bg.intLen; ++ i)
bg.decimal[i] = this->decimal[i] - x.decimal[i];
for(int i = 0; i < bg.intLen - 1; ++ i)
if(bg.decimal[i] < 0)
{
--bg.decimal[i + 1];
bg.decimal[i] += D_MOD;
}
for(int i = bg.intLen - 1; i > 0; -- i)
if(bg.decimal[i] == 0)
--bg.intLen;
else
break;
return bg;
}
//乘一个小于D_MOD的数
BigNumber operator * (int x) const
{
BigNumber bg;
if(x == 0)
return bg;
int tt, temp = 0;
bg.intLen = this->intLen;
for(int i = 0; i < this->intLen; ++ i)
{
tt = this->decimal[i] * x + temp;
bg.decimal[i] = tt % D_MOD;
temp = tt / D_MOD;
}
while(temp)
{
bg.decimal[bg.intLen++] = temp % D_MOD;
temp /= D_MOD;
}
return bg;
}
//移位操作,乘以D_MOD
void MoveOneStep()
{
for(int i = this->intLen - 1; i >= 0; -- i)
this->decimal[i + 1] = this->decimal[i];
if(this->decimal[this->intLen] != 0)
++this->intLen;
}
void OutPut()
{
printf("%d", this->decimal[this->intLen - 1]);
for(int i = this->intLen - 2; i >= 0; -- i)
printf("%02d", this->decimal[i]);
putchar('\n');
}
};
int Find_b(const BigNumber &a, const BigNumber &r)
{
BigNumber temp;
for(int b = 1; b < 10; ++ b)
{
temp = a * (20 * b) + b * b;
if(temp > r)
return b - 1;
else if(r == temp)
return b;
}
return 9;
}
bool Sqrt(const BigNumber &x)
{
BigNumber a, r;
int b, tLen = x.intLen - 1;
a.decimal[0] = (int)sqrt(x.decimal[tLen] + 0.5);
r.decimal[0] = x.decimal[tLen--] - a.decimal[a.intLen - 1] * a.decimal[a.intLen - 1];
while(tLen >= 0)
{
r.MoveOneStep();
r.decimal[0] = x.decimal[tLen--];
b = Find_b(a, r);
r = r - (a * (20 * b) + b * b);
a = a * 10 + b;
}
if(r.intLen==1&&r.decimal[0]==0)
return true;
return false;
}
const int numlen = 405; // 位数
int max(int a, int b) { return a>b?a:b; }
struct bign {
int len, s[numlen];
bign() {
memset(s, 0, sizeof(s));
len = 1;
}
bign(int num) {
if(num==0)
{
len=1;s[0]=0;return;
}
len = 0;
while(num>0)
{
s[len++]=num%10;
num/=10;
}
}
bign operator = (const char *num) {
len = strlen(num);
while(len > 1 && num[0] == '0') num++, len--;
for(int i = 0;i < len; i++) s[i] = num[len-i-1] - '0';
return *this;
}
void deal() {
while(len > 1 && !s[len-1]) len--;
}
bign operator + (const bign &a) const {
bign ret;
ret.len = 0;
int top = max(len, a.len) , add = 0;
for(int i = 0;add || i < top; i++) {
int now = add;
if(i < len) now += s[i];
if(i < a.len) now += a.s[i];
ret.s[ret.len++] = now%10;
add = now/10;
}
return ret;
}
bign operator - (const bign &a) const {
bign ret;
ret.len = 0;
int cal = 0;
for(int i = 0;i < len; i++) {
int now = s[i] - cal;
if(i < a.len) now -= a.s[i];
if(now >= 0) cal = 0;
else {
cal = 1; now += 10;
}
ret.s[ret.len++] = now;
}
ret.deal();
return ret;
}
bign operator * (const bign &a) const {
bign ret;
ret.len = len + a.len;
for(int i = 0;i < len; i++) {
for(int j = 0;j < a.len; j++)
ret.s[i+j] += s[i]*a.s[j];
}
for(int i = 0;i < ret.len; i++) {
ret.s[i+1] += ret.s[i]/10;
ret.s[i] %= 10;
}
ret.deal();
return ret;
}
bign operator / (const int a) const {
bign ret;
int cur = 0;
ret.len = len;
for(int i = len-1;i >= 0; i--) {
cur = cur*10+s[i];
while(cur >= a) {
ret.s[i]=cur/a;
cur %= a;
}
}
ret.deal();
return ret;
}
bool operator < (const bign &a) const {
if(len != a.len) return len < a.len;
for(int i = len-1;i >= 0; i--) if(s[i] != a.s[i])
return s[i] < a.s[i];
return false;
}
bool operator > (const bign &a) const { return a < *this; }
bool operator <= (const bign &a) const { return !(*this > a); }
bool operator >= (const bign &a) const { return !(*this < a); }
bool operator == (const bign &a) const { return !(*this > a || *this < a); }
bool operator != (const bign &a) const { return *this > a || *this < a; }
string str() const {
string ret = "";
for(int i = 0;i < len; i++) ret = char(s[i] + '0') + ret;
return ret;
}
};
bign o1,o2;
int main()
{
char str1[10]="1";
o1=str1;
str1[0]='2'; str1[1]='\n';
o2=str1;
int T;
cin>>T;
while(T--)
{
scanf("%s",str);
int len = strlen(str);
if(len == 1)
{
if(str[0]=='1')
{
cout<<"Arena of Valor"<<endl;
continue;
}
if(str[0]=='2')
{
cout<<"Clash Royale"<<endl;
continue;
}
}
bign n ;
n = str;
bign n1 = n-o1;
bign sn1 = (n*n1)/2;
BigNumber x(str);
for(int i = 0; i < sn1.len; i++)
{
str[sn1.len-1-i]=sn1.s[i]+'0';
}
str[sn1.len]='\0';
BigNumber y(str);
bool a1 = Sqrt(x);
bool a2 = Sqrt(y);
if(a1&&a2)cout<<"Arena of Valor"<<endl;
else if(a1) cout<<"Hearth Stone"<<endl;
else if(a2) cout<<"Clash Royale"<<endl;
else cout<<"League of Legends"<<endl;
}
return 0;
}
/*
Arena of Valor 1&1
Clash Royale 0&1
League of Legends 0&0
Hearth Stone 1&0
*/