PAT乙级-1011

1011 A+B和C (15)(15 分)提问

给定区间[-2^31^, 2^31^]内的3个整数A、B和C,请判断A+B是否大于C。

输入格式:

输入第1行给出正整数T(<=10),是测试用例的个数。随后给出T组测试用例,每组占一行,顺序给出A、B和C。整数间以空格分隔。

输出格式:

对每组测试用例,在一行中输出“Case #X: true”如果A+B>C,否则输出“Case #X: false”,其中X是测试用例的编号(从1开始)。

输入样例:

4
1 2 3
2 3 4
2147483647 0 2147483646
0 -2147483648 -2147483647

输出样例:

Case #1: false
Case #2: true
Case #3: true
Case #4: false

问题分析: 这道题卡了我挺长时间的,主要是对计算机存储数据的方式不熟,一开始觉着用int型,不考虑大数,感觉大数有点麻烦就偷了个懒,后来发现测试案例部分正确,后来就改了,int 4个字节 只能存储-2^31-2^31-1 范围内的数,所以该题不能用int。可以用long long 或者double 8个字节,-2^63-2^63-1,都能解决这个问题。但我后面是利用大数搞定的,花了一下午的时间,完成大数的加减乘,除法涉及到小数,需要用到浮点运算,比较麻烦,我就没写了。

小知识:int 4个字节 -2^31-2^31-1,数据大小长度小于10位 ;long long或者double 8个字节 数据大小长度小于19位;如果题目给的数据大于19位长度,则应使用字符串大数。如果用到long long,必需注意格式输入与输出,这个地方的错误我找了一个半小时,long long 8字节 64位,可以使用%I64d(g++)或者%lld(gcc)格式输入或输出,具体区别可参考这篇博文https://blog.csdn.net/piaocoder/article/details/50254117。下一章介绍大数。

算法分析:确定了数据大小,那这道题很容易就可以写出来,最近喜欢用链表,喜欢模块化编程,所以每次程序都有些长。下面分别给出long long 以及字符串大数两种代码。

扫描二维码关注公众号,回复: 2432972 查看本文章

long long:

#include <stdio.h>
#include <stdlib.h>

typedef struct LNode *List;
struct LNode{
	long long A;  
	long long B;  
	long long C; 
	List next;
};

List ReadInput(int n);
void fun(List L); /* 判断A+B>C */

int main()
{
	long long n=1;
	int m=1,i;
	printf("%d",sizeof(long long));
	for(i=0;i<30;i++)  /* 2^0+...+2^x=2^31-1 */ 
		m=(m<<1)+1;  /* << 优先级小于+ */ 
	for(i=0;i<62;i++)
		n=(n<<1)+1;
	printf("m=%d,n=%I64d",m,n);
 
/*	List L,P;
	int n;
	scanf("%d",&n);
	L = ReadInput(n);
/*	for(P=L;P!=NULL;P=P->next)
		printf("%I64d %I64d %I64d",P->A,P->B,P->C);
		*/
//	fun(L);	
	return 0;
} 

List ReadInput(int n)
{
	List L,P,t;
	int i=0;
	L = (List)malloc(sizeof(struct LNode));
	P = L;
	for(; i<n; i++)
	{
		t = P;
		scanf("%lld%lld%lld",&P->A,&P->B,&P->C);  
		/* 注意:long long 8字节 64位,可以使用%I64d(g++)或者%lld(gcc)格式输入或输出 */ 
		P = (List)malloc(sizeof(struct LNode));
		t->next = P; 
	}
	free(P);
	t->next = NULL;
	return L; 
}

void fun(List L) /* 判断A+B>C */
{
	List P=L;
	int i=1;
	for(; P->next!=NULL; P=P->next,i++)
	{
		if(P->A + P->B > P->C)	
			printf("Case #%d: true\n",i);
		else	printf("Case #%d: false\n",i);
	}
	if(P->A + P->B > P->C)		
			printf("Case #%d: true",i);
	else
		printf("Case #%d: false",i);	
} 

字符串数组大数(自己写的,代码有点长,有更简洁实现的欢迎交流进步):

#include <stdio.h>
#include <stdlib.h>

#define Length 13+1

typedef struct LNode *List;
struct LNode{
	char A[Length];  
	char B[Length];  
	char C[Length]; 
	List next;
};

List ReadInput(int n);
void fun(List L); /* 判断A+B>C */
void LInput(char *a);   /* 大数输入 */
void LOutput(char *a);   /* 大数输出 */ 
int StrLen(char *a); /* 求大数长度 */ 
int Compare(char *a,char *b);  /* a,b为整数,a>b 返回1,否则返回0 */
int PCompare(char *a,char *b);  /* a,b均大于0,a>b 返回1,否则返回0 */ 
void fun1(char *a,char *b,char *t);                /* 大数为正相加 */
void fun2(char *a,char *b,char *t);                 /* 大数为正相减 */
void LAdd(char *a,char *b,char *c);                  /* 大数相加 */

int main()
{
	List L,P;
	int n;
	scanf("%d",&n);
	L = ReadInput(n);
	fun(L);	
	return 0;
} 

List ReadInput(int n)
{
	List L,P,t;
	int i=0;
	L = (List)malloc(sizeof(struct LNode));
	P = L;
	getchar();
	for(; i<n; i++)
	{
		t = P;
		LInput(P->A);
		LInput(P->B);
		LInput(P->C);
		P = (List)malloc(sizeof(struct LNode));
		t->next = P; 
	}
	free(P);
	t->next = NULL;
	return L; 
}

void fun(List L) /* 判断A+B>C */
{
	List P=L;
	char t[Length];
	int i=1;
	for(; P->next!=NULL; P=P->next,i++)
	{
		LAdd(P->A,P->B,t);
//			LOutput(t);
		if(Compare( t, P->C))	
			printf("Case #%d: true\n",i);
		else	printf("Case #%d: false\n",i);
	}
	LAdd(P->A,P->B,t);
//	LOutput(t);
	if(Compare( t, P->C))	
			printf("Case #%d: true",i);
		else	printf("Case #%d: false",i);
} 

void LInput(char *a)   /* 大数输入,最高位前面的初始化为'0' */ 
{
	int i,j;
	char t;
	for(i=0;i<Length;i++)
	{
		scanf("%c",&a[i]);
		if(a[i]=='\n' || a[i]==' ')
		{
			j=i-1;     /* 记住输入字符长度 */ 
			while(i<Length)	a[i++]='0';  /* 补零 */ 
			break;
		}
	}
	if(i==Length) a[i-1]='\0';   /* 字符串最后一位'\0' */ 
	/* 逆序,高位存储在高字节 */ 
	for(i=0;i<=j;i++,j--)
	{
		t=a[i];
		a[i]=a[j];
		a[j]=t; 
	}	 
}
void LOutput(char *a)   /* 大数输出 */ 
{
	int j=StrLen(a)-1;
	if(a[0]=='\0')	printf("溢出\n");
	if(j==-1)    printf("%d",a[j]);   /* 0 的情况 */ 
	else
	for(;j>=0;j--)
		printf("%c",a[j]);
	printf("\n");
}
int StrLen(char *a)  /* 求大数长度,包括正负号 */ 
{
	int i;
	while(*a)	a++;   /* 从后序开始查找 */ 
	for(i=0;;i++)
		if(*--a !='0')	break;
	return Length-i-1;	
}
int Compare(char *a,char *b)  /* a>b 返回1,否则返回0 */ 
{
	int L1=StrLen(a)-1,L2=StrLen(b)-1;
	char a1[Length],a2[Length],i;
	/* a>=0,b<0 */ 
	if(a[L1]!='-' && b[L2]=='-')	
		return 1;
	/* a<0,b>=0 */ 
	if(a[L1]=='-' && b[L2]!='-')	return 0;
	/* a<0,b<0 */ 
	for(i=0;i<Length;i++)  /* 先存储,再使用,防止a,b的值被改变 */ 
	{
		a1[i] = a[i];
		a2[i] = b[i];
	}
	if((a[L1] == '-') && (b[L2] == '-'))
	{
		a1[L1]=a2[L2]='0';
		if(PCompare(a1,a2)) return 0;
		else return 1;
	}
	/* a>=0,b>=0 */
	return PCompare(a1,a2);  
}

int PCompare(char *a,char *b)  /* a,b均大于0,a>b 返回1,否则返回0 */ 
{
	int l1=StrLen(a)-1,l2=StrLen(b)-1;
	if(l1>l2)
		return 1;
	if(l1<l2)
		return 0;
	for(;l1>=0;l1--)
	{
//		printf("a[%d]=%c,b[%d]=%c\n",l1,a[l1],l1,b[l1]);	
		if(a[l1]>b[l1])	return 1;
		if(a[l1]<b[l1]) return 0; 
	}
	return 0;
}

void LAdd(char *a,char *b,char *c)                  /* 大数相加 */
{
	int L1=StrLen(a)-1,L2=StrLen(b)-1,l;
	/* a>0,b>0,a+b */
	if(a[L1]!='-' && b[L2]!='-')	   
		fun1(a,b,c);            
	/* a>0,b<0,转化成a-|b| */              
	if(a[L1]!='-' && b[L2]=='-')             
	{
		b[L2]='0';
		if(Compare(a,b))                      /* 若a>=|b|,则a-|b|,否则-(|b|-a) */ 
			fun2(a,b,c);    
		else
		{
			fun2(b,a,c);
			c[StrLen(c)]='-';
		}                         
	}
	/* a<0,b>0,转化成b-|a| */
	if(a[L1]=='-' && b[L2]!='-')		
	{
		a[L1]='0';
		if(Compare(b,a))                      /* 若b>=|a|,则b-|a|,否则-(|a|-b) */ 
			fun2(b,a,c);    
		else
		{
			fun2(a,b,c);
			c[StrLen(c)]='-';
		}                 
	}	
	/* a<0,b<0,转化成-(|b|+|a|) */
	if(a[L1]=='-' && b[L2]=='-')   
	{
		a[L1]='0';
		b[L2]='0';
		fun1(a,b,c);                     
		l=StrLen(c);
		c[l]='-';
	}
}

void fun1(char *a,char *b,char *t)                  /* 大数为正相加 */
{
	int i,c=0,s;        /* c进位 */ 	
	for(i=0;i<Length;i++)
	{
		s = a[i]-'0'+b[i]-'0';  
		if(s<10)           
		{
			t[i]=s+'0'+c;
			c=0;
		}
		else
		{
			t[i]=s-10+'0'+c;
			c=1;
		}			
	}
	if(c == 1)  /* 最高位进位,溢出 */ 
		t[0] = '\0';
	else       
		t[i-1] = '\0';
}

void fun2(char *a,char *b,char *t)                  /* 大数为正相减,且a>b */
{
	int i,c=0,s;        /* c借位 */ 
	for(i=0;i<Length;i++)   
	{
		s = a[i]-'0'-(b[i]-'0'); 
		if(s>=0)           
		{
			t[i]=s+'0'-c;
			c=0;
		}
		else
		{
			t[i]=s+10+'0'-c;
			c=1;
		}			
	}
	if(c == 1)  /* 最高位借位,溢出 */ 
		t[0] = '\0';
	else
		t[i-1] = '\0';
}

猜你喜欢

转载自blog.csdn.net/bridge3/article/details/81191490
今日推荐