CSUOJ 2034:Column Addition

2034: Column Addition

Description

A multi-digit column addition is a formula on adding two integers written like this:
在这里插入图片描述
A multi-digit column addition is written on the blackboard, but the sum is not necessarily correct. We can erase any number of the columns so that the addition becomes correct. For example, in the following addition, we can obtain a correct addition by erasing the second and the forth columns.
在这里插入图片描述
Your task is to find the minimum number of columns needed to be erased such that the remaining formula becomes a correct addition.

Input

There are multiple test cases in the input. Each test case starts with a line containing the single integer n, the number of digit columns in the addition (1 ⩽ n ⩽ 1000). Each of the next 3 lines contain a string of n digits. The number on the third line is presenting the (not necessarily correct) sum of the numbers in the first and the second line. The input terminates with a line containing “0” which should not be processed.

Output

For each test case, print a single line containing the minimum number of columns needed to be erased.

Sample Input

3
123
456
579
5
12127
45618
51825
2
24
32
32
5
12299
12299
25598
0

Sample Output

0
2
2
1

Hint

据说这题要用dp做,身为萌新的自己大概看了一下算法书上的知识点,假装懂了,关键大概就是要找出递推式吧。很容易想到有五种情况,为了构造递推需要两个函数同时进行, f1[n]存储首项为n的情况下首项进一至少需要删去的个数, f2[n]存储首项为n的情况下首项不进一至少需要删去的个数。兴致冲冲地写好,WA,怎么可能呢我这么精妙的算法怎么可能有问题呢(内心咆哮)。经过坚持不懈地调试,果然还是递推式出了问题,关键就是这几行代码,最后需要比较才能确定。

else if (stack[i - 1] == 3)
			{
				if (f1[i - 1] == i - 1)//细节1:这个细节坑我不浅,全删了就失效了
					f0[i] = i;
				else
					f0[i] = f1[i - 1];
				if (f0[i] > f0[i - 1] + 1)//细节2:这个细节也坑我不浅,显然是经验不足,没有真正把握住最优
					f0[i] = f0[i - 1] + 1;
			}
			else if (stack[i - 1] == 4)
			{
				f1[i] = f0[i - 1];
				if (f1[i] > f1[i - 1] + 1)//同细节2
					f1[i] = f1[i - 1] + 1;
			}
			else if (stack[i - 1] == 5)
			{
				if (f1[i - 1]== i -1)//同细节1
					f1[i] = i;
				else
					f1[i] = f1[i - 1];
			}

在这里插入图片描述

#include<stdio.h>
#define N 1005
int a[N];
int b[N];
int c[N];
int stack[N];
int f0[N];			//保存递推数的两个数组
int f1[N];
int top;
int n;
void scan(int a[], int n);
int main()
{
	while (scanf("%d", &n) != EOF && n != 0)
	{
		top = 0;
		scan(a, n);
		scan(b, n);
		scan(c, n);
		for (int i = n - 1; i >= 0; i--)
		{
			if (a[i] + b[i] == c[i])//将符合标记为1
			{
				stack[top++] = 1;
			}
			else if (a[i] + b[i] == c[i] - 1)//将差一标记为3
			{
				stack[top++] = 3;
			}
			else if (a[i] + b[i] - 10 == c[i])//将进一标记为4
			{
				stack[top++] = 4;
			}
			else if (a[i] + b[i] - 10 == c[i] - 1)//将前一位进一自身又进一标记为5
			{
				stack[top++] = 5;
			}
			else
			{
				stack[top++] = 2;
			}
		}
		f0[0] = 0;
		f1[0] = 0;
		for (int i = 1; i <= n; i++)
		{
			if (stack[i - 1] == 1)
			{
				f0[i] = f0[i - 1];
				f1[i] = f1[i - 1] + 1;
			}
			else if (stack[i - 1] == 2)
			{
				f0[i] = f0[i - 1] + 1;
				f1[i] = f1[i - 1] + 1;
			}
			else if (stack[i - 1] == 3)
			{
				if (f1[i - 1] == i - 1)
					f0[i] = i;
				else
					f0[i] = f1[i - 1];

				if (f0[i] > f0[i - 1] + 1)
					f0[i] = f0[i - 1] + 1;

				f1[i] = f1[i - 1] + 1;
			}
			else if (stack[i - 1] == 4)
			{
				f0[i] = f0[i - 1] + 1;

				f1[i] = f0[i - 1];

				if (f1[i] > f1[i - 1] + 1)
					f1[i] = f1[i - 1] + 1;
			}
			else if (stack[i - 1] == 5)
			{
				f0[i] = f0[i - 1] + 1;

				if (f1[i - 1]== i -1)
					f1[i] = i;
				else
					f1[i] = f1[i - 1];
			}
		}
		printf("%d\n", f0[n]);
	}
	return 0;
}
void scan(int a[], int n)
{
	for (int i = 0; i < n; i++)
	{
		scanf("%1d", &a[i]);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值