算法强训day6

今天的三道题类型都是差不多的,很好写。

一、大数相加

链接:大数加法_牛客题霸_牛客网

从个位开始,满十进一,用的是数组存放数据

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 计算两个数之和
 * @param s string字符串 表示第一个整数
 * @param t string字符串 表示第二个整数
 * @return string字符串
 */
#include <string.h>
#include<stdio.h>
char* solve(char* s, char* t) {

	int a = strlen(s);
	int b = strlen(t);
	if (b == 0)
		return s;
	if (a == 0)
		return t;
	int x = a > b ? a : b;

	char arr[10000000] = { 0 };
	int n = x;
	arr[x + 1] = 0;
	while (a && b)
	{
		if (arr[x] == 0)
			arr[x] = '0';
		int m = s[a - 1] - '0' + t[b - 1] - '0' + arr[x] - '0';
		if (arr[x - 1] == 0)
			arr[x - 1] = '0';
		arr[x - 1] = arr[x - 1] + m / 10;
		arr[x] = m / 10 + '0';
		arr[x] = m % 10 + '0';
		x--;
		a--;
		b--;
	}
	if (a)
	{
		a--;
		while (a > -1)
		{
			if (arr[x] == 0)
				arr[x] = '0';
			int m = s[a] - '0' + arr[x] - '0';
			if (m >= 10)
			{
				if (arr[x - 1] == 0)
					arr[x - 1] = '0';
				arr[x - 1] = arr[x - 1] + m / 10;
			}
			if (m == 10)
				arr[x] = '0';
			else
				arr[x] = m % 10 + '0';
			a--;
			x--;
		}
	}
	if (b)
	{
		b--;
		while (b > -1)
		{
			if (arr[x] == 0)
				arr[x] = '0';
			int m = t[b] - '0' + arr[x] - '0';
			if (m >= 10)
			{
				if (arr[x - 1] == 0)
					arr[x - 1] = '0';
				arr[x - 1] = arr[x - 1] + m / 10;
			}
			if (m == 10)
				arr[x] = '0';
			else
				arr[x] = m % 10 + '0';
			b--;
			x--;
		}
	}
	/*int i = 0;
	for (i = 0; i <= n; i++)
		printf("%c", arr[i]);*/
	if (arr[0] == 0 || arr[0] == '0')
		return arr + 1;
	return arr;
}

二、链表相加

链接:链表相加(二)_牛客题霸_牛客网

和上道题差不多,只不过用链表存放数据


/**

  * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
  *
  *
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
#include<stdio.h>

void PushHead(struct ListNode** head, int v)
{
	struct ListNode* p = (struct ListNode*)malloc(sizeof(struct ListNode));
	p->next = *head;
	p->val = v;
	*head = p;
}
void pop(struct ListNode** head)
{
	struct ListNode* p = (*head)->next;
	free(*head);
	*head = p;
}
int arr1[1000000] = { 0 };
int arr2[1000000] = { 0 };
struct ListNode* addInList(struct ListNode* head1, struct ListNode* head2)
{
	struct ListNode* head = NULL;

	int a = 0;
	int b = 0;
	while (head1)
	{
		arr1[a++] = head1->val;
		head1 = head1->next;
	}
	while (head2)
	{
		arr2[b++] = head2->val;
		head2 = head2->next;
	}
	int n = a > b ? b : a;
	PushHead(&head, 0);

	while (n--)
	{
		int x = arr1[--a] + arr2[--b] + head->val;
		PushHead(&head, 0);
		head->val = x / 10;
		head->next->val = x % 10;
	}
	if (a)
	{
		while (a--)
		{
			int x = head->val + arr1[a];
			head->val = x % 10;
			PushHead(&head, x / 10);
		}
	}
	else
	{
		while (b--)
		{
			int x = head->val + arr2[b];
			head->val = x % 10;
			PushHead(&head, x / 10);
		}
	}
	while (head->val == 0)
	{

		head = head->next;
	}
	return head;
}

三、大数相乘

链接:大数乘法_牛客题霸_牛客网

这道题应该是今天最难的一道,用一个数的每一位乘另一个数的每一位,再算某一位数时,要考虑前两位,如9*9=81,如果前一位和8相加满十,前两位要进一。

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 计算两个数之和
 * @param s string字符串 表示第一个整数
 * @param t string字符串 表示第二个整数
 * @return string字符串
 */
#include <string.h>
#include<stdio.h>
char arr[1000000009] = { 0 };
char arr2[2] = { '0' };
char* solve(char* s, char* t) {
	long long a = strlen(s);
	long long b = strlen(t);

	if (s[0] == '0' || t[0] == '0')
		return arr2;
	long long x = a + b + 3;
	long long z = x;
	long long n = a > b ? a : b;
	char* max = NULL;
	char* min = NULL;

	if (n == a)
	{
		max = s;
		min = t;
	}
	else
	{
		max = t;
		min = s;
	}
	while (n--)
	{
		long long now = x;
		long long i = a > b ? b : a;
		i--;
		for (i; i >= 0; i--)
		{
			if (arr[now] == 0)
				arr[now] = '0';
			long long m = (max[n] - '0') * (min[i] - '0') + arr[now] - '0';
			if (arr[now - 1] == 0)
				arr[now - 1] = '0';
			long long f = arr[now - 1] - '0' + m / 10;
			if (arr[now - 2] == 0)
				arr[now - 2] = '0';
			arr[now - 2] = arr[now - 2] + f / 10;

			arr[now - 1] = f % 10 + '0';
			arr[now] = m % 10 + '0';
			now--;
		}
		x--;
	}
	int j = 0;
	while (arr[j] == 0 || arr[j] == '0')
		j++;
	return arr + j;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值