一、概述
给出两个数字A和B,按位分奇偶进行操作。很简略的一道题。其坑的程度对于我来说直逼PAT A1002。
二、分析
给出加密用正整数A以及待加密数B,从个位开始,以个位为第一位,分别按奇偶进行处理。好,到这里还是正常,接下来的隐藏条件就得一点一点猜了,如果两个数不一样长,会出现什么情况?
以下是我的猜测:
根据给出的例子,B比A长,B的剩余部分直接成为结果。则推测A比B长的时候不输出。结果测试点2和5过不去。
继续猜测。
A比B长的时候输出A的输出A的剩余部分。结果还是过不去。
继续猜测。
对于结果进行前面补零的操作,使得结果与较长的一样长。过不去。
继续猜测。
猜不出。
上网查询。
方法和我的都不一样,翻转过来再处理。
嗯?特殊之处在于对于不一样长的数,在后面补零。
卧槽,原来是A比B长的时候B要补零啊。那不就是按A的剩余输出吗?
不对,偶数是B-A,B为零那减完就是负数了,要加10!所以不是A的剩余部分成为结果,是10-A才对。
测试点2过了,5没过。
猜测问题还是出在这里。
偶然发现当B-A=0的时候,加10输出的是J而不是0,从而,最后的bug也被找到了。
如图
下面是我的算法:
我并没有使用翻转的方法,最开始觉得写一个函数太麻烦,后来才知道我是多么幼稚。
不翻转,那么数组的下标就会很复杂。
B比A长的情况下,如下
for (i = lengthB - 1; i >lengthB - lengthA - 1; i--)
{
if ((lengthB - i) % 2 == 0)
if (B[i] - A[lengthA - (lengthB - i)] >= 0)
Answer[i] = B[i] - A[lengthA - (lengthB - i)];
else
Answer[i] = B[i] - A[lengthA - (lengthB - i)] + 10;
else
{
Answer[i] = (A[lengthA - (lengthB - i)] + B[i] - 96) % 13;
}
}
for (i = lengthB - lengthA - 1; i >= 0; i--)
Answer[i] = B[i] - 48;
int m = 0;
while (num[Answer[m]] == '0')
m++;
for (i = m; i < lengthB; i++)
{
printf("%c", num[Answer[i]]);
}
个位作为第一位,那么就要从后向前来数,角标与第几位的转换关系也很容易弄混。另外,测试点没有首部出现多个零的情况,对于这一情况我也考虑到了,oj还是不够严密。
A比B长的情况下,如下
for (i = lengthB - 1; i >= 0; i--)
{
if ((lengthB - i) % 2 == 0)
if (B[i] - A[lengthA - (lengthB - i)] >= 0)
Answer[lengthA - (lengthB - i)] = B[i] - A[lengthA - (lengthB - i)];
else
Answer[lengthA - (lengthB - i)] = B[i] - A[lengthA - (lengthB - i)] + 10;
else
Answer[lengthA - (lengthB - i)] = (A[lengthA - (lengthB - i)] + B[i] - 96) % 13;
}
for (i = lengthA - lengthB - 1; i >= 0; i--)
{
/*if ((i + 1) % 2 != 0)
Answer[i] = A[i] - 48;
else
if (A[i] == 0)
Answer[i] = 0;
else
Answer[i] = 10 - (A[i] - 48);*/
if((lengthA-i)%2!=0)
Answer[i] = A[i] - 48;
else
if (A[i] == '0')//我就是个傻逼
Answer[i] = 0;
else
Answer[i] = 10 - (A[i] - 48);
}
int m = 0;
while (num[Answer[m]] == '0')
m++;
for (i = m; i < lengthA; i++)
{
printf("%c", num[Answer[i]]);
}
数组下标如果不确定的话,就f10一步一步走,走两遍就能全改好了,真的靠算的话很费时间,还可能不对。
这里有一个小bug,就是我进行了string到char到int的转换,在检查是否为零时,开始0没加单引号,而且没检查出来,又多耗费了一点时间,很气。
三、总结
检查点不过的原因有很多,无外乎特殊值如0,1,最大值没考虑到;char转int没减48;字符串类的空字符串,满字符串等;还有一大部分是题意没理解好,这个是最坑的,多加一个样例可以节约很多很多时间。很是不愿放弃自己写了很久的代码。
PS:代码如下
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
char num[13] = { '0','1','2','3','4','5','6','7','8','9','J','Q','K' };
int main()
{
string A, B;
cin >> A;
cin >> B;
int lengthA = A.length();
int lengthB = B.length();
int Answer[110] = { 0 };
int count, answerl;
int i;
if (lengthA < lengthB)
{
for (i = lengthB - 1; i >lengthB - lengthA - 1; i--)
{
if ((lengthB - i) % 2 == 0)
if (B[i] - A[lengthA - (lengthB - i)] >= 0)
Answer[i] = B[i] - A[lengthA - (lengthB - i)];
else
Answer[i] = B[i] - A[lengthA - (lengthB - i)] + 10;
else
{
Answer[i] = (A[lengthA - (lengthB - i)] + B[i] - 96) % 13;
}
}
for (i = lengthB - lengthA - 1; i >= 0; i--)
Answer[i] = B[i] - 48;
int m = 0;
while (num[Answer[m]] == '0')
m++;
for (i = m; i < lengthB; i++)
{
printf("%c", num[Answer[i]]);
}
}
else
{
for (i = lengthB - 1; i >= 0; i--)
{
if ((lengthB - i) % 2 == 0)
if (B[i] - A[lengthA - (lengthB - i)] >= 0)
Answer[lengthA - (lengthB - i)] = B[i] - A[lengthA - (lengthB - i)];
else
Answer[lengthA - (lengthB - i)] = B[i] - A[lengthA - (lengthB - i)] + 10;
else
Answer[lengthA - (lengthB - i)] = (A[lengthA - (lengthB - i)] + B[i] - 96) % 13;
}
for (i = lengthA - lengthB - 1; i >= 0; i--)
{
/*if ((i + 1) % 2 != 0)
Answer[i] = A[i] - 48;
else
if (A[i] == 0)
Answer[i] = 0;
else
Answer[i] = 10 - (A[i] - 48);*/
if((lengthA-i)%2!=0)
Answer[i] = A[i] - 48;
else
if (A[i] == '0')//我就是个傻逼
Answer[i] = 0;
else
Answer[i] = 10 - (A[i] - 48);
}
int m = 0;
while (num[Answer[m]] == '0')
m++;
for (i = m; i < lengthA; i++)
{
printf("%c", num[Answer[i]]);
}
}
}