HDU 2116 Has the sum exceeded (大数)

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


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值