这题看起来很简单,可惜某渣还是做了很久啊,代码写了之后一直WA 而且找不出到底错在哪,今天我终于找出来了。o(∩_∩)o 哈哈
题意: 给你一个K,给你一个X,Y判断X,Y的和是否在-2^k至2^k-1之间,X,Y一定在该区间
思路: 因为2<=K<=64 ,所以我先用大数记录了2的1-63次方,然后判断
情况1: x<=0&&y>=0 OR x>=0&&y<=0
易得该情况下X+Y 一定会在区间内
情况2: X>=0 && Y>=0
判断X+Y+1 是否小于或等于2^K即可,然后大数加法算出X= X +Y,然后大数加法X = X+ 1( 因为正区间最大为2^k-1 , 所以X和Y的和需加1)
情况3: X<=0 && Y<= 0
判断 - (X+Y) 是否小于或等于2^k即可, 在将X 转化为-X的时候需注意,因为负区间方向比正区间方向多1,所以当x= -2^k 时,直接X= -X 会错
所以我们需要 X++,Y++, 然后X= -X,Y=-Y ; 然后和情况2一样,用大数加法算出X= X+ Y, 由于之前减了2 所以这里需要再用大数加法X= X+2(之前我就X= -X, Y=-Y, 然后直接加,然后某渣就一直WA, 哭瞎了都,实力实在太弱。。)
代码:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<limits.h>
using namespace std;
int A[30],B[30];
int C[70][30];// 2的i次方
void Add(int a[],int b[],int d[])
{
int c[30];
memset(c,0,sizeof(c));
int max= a[0] > b[0] ?a[0]: b[0];
c[0]= max;
for(int i= 1; i<= max; i++)
{
c[i]=c[i] + a[i]+ b[i];
if(c[i]> 9)
{
c[i]%= 10;
c[i+1]++;
}
}
if(c[max+1])
{
max++;
c[0]++;
}
d[0]= c[0];
for(int i= 1; i<= d[0]; i++)
d[i]= c[i];
}
int Max(int a[],int b[])
{
if(a[0] != b[0])
return a[0] > b[0];
else
{
for(int i= a[0]; i>= 1; i--)
if(a[i]!=b[i])
return a[i] > b[i];
}
return 1;
}
int main()
{
memset(C,0,sizeof(C));
C[1][0]= 1;
C[1][1]= 2;
for(int i= 1; i<= 63; i++)
Add(C[i],C[i],C[i+1]);
int k;
while(scanf("%d",&k)!=EOF)
{
__int64 x,y;
scanf("%I64d %I64d",&x,&y);
if((x<= 0 && y>= 0)||(x>= 0 && y<= 0))
{
printf("WaHaHa\n");
continue;
}
int flag= 0;
if(x>= 0 && y>= 0)
flag= 1;
if(x<= 0 && y<= 0)
{
flag= 2;
x++;
y++; //(这里不加1会错)
x= -x;
y= -y;
}
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
while(x)
{
A[0]++;
A[A[0]]= x%10;
x/= 10;
}
while(y)
{
B[0]++;
B[B[0]]= y%10;
y/= 10;
}
Add(A,B,A);
if(flag)
{
int hehe[30];
memset(hehe,0,sizeof(hehe));
hehe[0]= 1;
hehe[1]= flag;
Add(A,hehe,A);
}
if(Max(C[k-1],A))
printf("WaHaHa\n");
else
printf("Yes\n");
}
return 0;
}