这题看起来很简单,可惜某渣还是做了很久啊,代码写了之后一直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; }