喜极而泣!杭电OJ——1002 A + B Problem II

本文介绍了一种解决大数相加问题的方法,通过使用字符串输入和数组进行逐位相加,有效地处理了超出基本数据类型表示范围的情况。

A + B Problem II



Problem Description
I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.

Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line consists of two positive integers, A and B. Notice that the integers are very large, that means you should not process them by using 32-bit integer. You may assume the length of each integer will not exceed 1000.

Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line is the an equation "A + B = Sum", Sum means the result of A + B. Note there are some spaces int the equation. Output a blank line between two test cases.

Sample Input
2 1 2 112233445566778899 998877665544332211

Sample Output
Case 1: 1 + 2 = 3 Case 2: 112233445566778899 + 998877665544332211 = 1111111111111111110

在杭电上交了12次,终于AC,掩饰不住心中的激动!特发此文,以表纪念!

这是一道大数相加的题目,测试数据已经远远超过了基本数据的表示范围,要用数组一位位相加!

以下是AC代码:

仅供参考

//设想:建立一个数组储存加的值
//经验总结:细心,细心,再细心!不然太容易出错!!!
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;

int main()
{
	string a,b;
	int num,sum[1000];//数组尽量开大点,不然很容易越界!
    cin>>num;
	for(int l=0;l<num;l++)
	{
		cin>>a>>b;
		int m=0,n=0,temp=0,i,k;
		int	q=0;//用于记录sum数组的长度!!
	    i=a.length();
	    k=b.length();
		//for(i=0;a[i]!='\0';i++);
	//for(k=0;b[k]!='\0';k++);
		i=i-1;
		k=k-1;
       // cout<<"刚开始时 i="<<i<<"  "<<"k="<<k<<endl;
		while(i>=0 && k>=0)//像是这样加,会一直加到一个数加完
		{
			m=a[i]-'0';
		//	cout<<"m="<<m<<" ";
			n=b[k]-'0';
		//	cout<<"n="<<n<<endl;
		
			sum[q++]=(temp+m+n)%10;
		//	cout<<"sum[q-1]="<<sum[q-1]<<endl;
			temp=(temp+m+n)/10;//temp取进位,并且加到下一次的加法中
			//cout<<"temp="<<temp<<endl;
		//	cout<<"q="<<q<<endl;
			i--;
			k--;
		//	cout<<"i="<<i<<" "<<"k="<<k<<endl;
		//	cout<<endl;
		}
		//还需要处理一个长度的问题,判断哪个长,哪个短!
	  if(i>k)//a数比较大,确切的说是比较长!
	  {//cout<<"I am 1"<<endl;
		  while(i>=0)
		  {
		     
			 m=a[i]-'0';
			 sum[q++]=(temp+m)%10;
		     temp=(temp+m)/10;//坑爹的坑,在这里坑了一次,我本来是temp+m+n,然后不知为何错了,很难察觉的!

			 i--;
		  }
	  }
	  if(k>i)
	  {
		 // cout<<"I am 2"<<endl;
		// cout<<"k="<<k<<" "<<"temp="<<temp<<endl;
		 while(k>=0)
		  {
		     m=b[k]-'0';//这里也被坑了一次,我把b写成了a,全是复制粘贴惹的祸
			//cout<<"m="<<m<<endl;
			 sum[q++]=(temp+m)%10;
            //cout<<"sum[q-1]="<<sum[q-1]<<endl;
		     temp=(temp+m)/10;
			 k--;
		  }
	  }
	  sum[q]=temp;
	 // for(i=50;;i--)
		 // if(sum[i]!=0)
		//	  break;
		  //for(i++;i>=0;i--)
	  cout<<"Case "<<l+1<<":"<<endl;
	 cout<<a<<" + "<<b<<" = ";
	  if(sum[q]!=0) cout<<sum[q];
		  for(--q;q>=0;q--)
          cout<<sum[q];
	 //printf("%d",sum[--q]);//第一个测试数据成功!
	// for(--q;q>=0;q--)
	// {
	//	 printf("%04d",sum[q]);
	// }
	 cout<<endl;
	 if(l<num-1) cout<<endl;

	}//for
 return 0;
}


### 杭电OJ C++编程题解与解决方案 杭电OJ是一个重要的编程技能提升平台,它提供了丰富的题目资源,帮助学习者掌握基础算法、数据结构以及高级编程技术[^3]。以下是针对杭电OJ上常见的C++编程问题及其解决方法的一些讨论。 #### 题目类型分析 杭电OJ中的题目通常涉及以下几个方面: 1. **基本控制流**:如`for`, `while`循环的应用。 2. **数组操作**:包括一维数组和二维数组的操作。 3. **字符串处理**:涉及到字符匹配、子串提取等问题。 4. **数学逻辑**:利用数论知识解决问题。 5. **指针应用**:深入理解内存管理机制。 6. **复杂数据结构**:链表、栈、队列等的实际运用。 下面给出几个具体的例子并附带相应的代码实现: #### 示例一:反转整数并与原数值比较 此问题是关于如何逆向构建一个整数,并验证其特定条件下的性质。 ```cpp #include <iostream> using namespace std; // 定义函数用于计算给定数字a的反序形式 int reverseInt(int a){ int res = 0; while(a != 0){ res = res * 10 + a % 10; a /= 10; } return res; } int main(){ bool found = false; for(int i = 1000; i <= 1111; ++i){ if(reverseInt(i) == i * 9){ cout << i << endl; found = true; } } if(!found){ cout << "No such number exists." << endl; } } ``` 上述程序展示了如何遍历一定范围内的所有可能值,并检查它们满足某些特殊关系的能力[^1]。 #### 示例二:双指针法寻找符合条件的一对索引 当面对需要优化时间复杂度的任务时,“双指针”是一种非常有效的策略。 假设我们有一个未排序列表,目标是从其中找到两个元素使得它们之差等于指定常量k,则可以通过如下方式高效求解: ```cpp #include <vector> #include <algorithm> // sort function needed here. using namespace std; pair<int, int> findPairWithDifference(const vector<int>& nums, const int k){ pair<int,int> result(-1,-1); // Sort the array first to apply two pointer technique effectively. vector<int> sortedNums(nums); sort(sortedNums.begin(),sortedNums.end()); size_t left = 0 ; size_t right = 1 ; while( right < sortedNums.size()){ long diff = static_cast<long>(sortedNums[right]) - static_cast<long>(sortedNums[left]); if(diff == k ){ result.first=sortedNums[left]; result.second=sortedNums[right]; break; } if(diff<k )right++; else if(diff>k &&left<right-1)left++; else{ // To avoid infinite loop when both pointers are at same position and difference is zero or negative. right++; left++; } } return result; } ``` 这里采用了先排序再用双指针扫描的方法来快速定位合适的配对项[^5]。 #### 进一步探讨——环形链表检测及入口节点确定 对于更复杂的场景比如判定单链表是否存在闭环并且找出这个闭合点的位置,可以采用快慢指针的技术路线。 ```cpp struct ListNode { int val; ListNode *next; ListNode(int x):val(x), next(NULL){} }; ListNode* detectCycle(ListNode *head){ if(head==NULL || head->next==NULL)return NULL; ListNode *slow=head,*fast=head; do{ slow=slow->next; fast=(fast->next!=NULL)?fast->next->next:NULL; }while(fast&&slow!=fast); if(slow!=fast||!fast)return NULL;// No cycle detected. slow=head; while(slow!=fast){ slow=slow->next; fast=fast->next; } return slow; } ``` 这段代码实现了不仅能够确认是否含有环路而且还能准确定位到入环首结点的功能[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值