题目链接在此。
思路及AC代码
我们用字符串数组保存两个输入,由于两个字符串的长度可能不相等,为了方便两个字符串的相同位进行运算,我们有两种解决思路:
我的思路
记录两个字符串的长度分别为lena,lenb,lena和lenb作比较,稍长的那个记作len_max,两个长度差值的绝对值记作dis。
想将稍短的字符串所有位都向后移动dis个位置,前面0~dis-1的位置补上’0’,这样之后,两个字符串就对对齐了,直接实现题目中的算法即可。
但是这种思路会遇到一个坑:奇数位和偶数位的判定。
这里只稍做根本原因上的提示,至于判定方法,非常多样,只需要能够判定方法能够做到奇偶交替,和题目中要求的奇偶性对上即可。
“坑”的提示:
由于从右往左的第一位为奇数位,当len_max=4时,从左往右的第一位为偶数位,len_max=5时,* 从左往右*的第一位为奇数位。
AC代码
#include<stdio.h>
#include<string.h>
char mp[] = {'0','1','2','3','4','5','6','7','8','9','J','Q','K'};
int main(){
char a[101],b[101];
scanf("%s %s",a,b);
int lena = strlen(a);
int lenb = strlen(b);
int len_max = (lena > lenb) ? lena : lenb;
//先移动元素,使得a,b数组元素对齐
if(lena < lenb){
int dis = lenb-lena;
//a往后移动dis个位置
for(int i = lena-1; i >= 0; i--){
a[i+dis] = a[i];
}
//给a数组的0~dis-1赋值为'0'
for(int i = 0; i < dis; i++){
a[i] = '0';
}
} else if(lena > lenb){
int dis = lena-lenb;
for(int i = lenb-1; i >= 0; i--){
b[i+dis] = b[i];
}
for(int i = 0; i < dis; i++){
b[i] = '0';
}
}//else lena==lenb ,则可直接运算
//实现题目算法
int res;
int index = 0;
for(int i = 0; i < len_max; i++){
//尤其注意奇偶性的判定
if((len_max-i+1)%2){ //对应于题目的偶数位情况
res = (b[i]-'0')-(a[i]-'0');
if(res<0){
res += 10;
}
printf("%c",mp[res]);
} else{ //对应于题目的奇数位情况
res = ((a[i]-'0')+(b[i]-'0'))%13;
printf("%c",mp[res]);
}
}
return 0;
}
《算法笔记》思路
《算法笔记》的思路在大体上和我的一致,两者的区别也就差在如何对齐上。
《算法笔记》中的对齐是将两个字符串都逆序保存,在短的那个字符串的后面补上dis个’0’,之后的算法实现就和上面的一致了。
但是这种方法完美的避开了上面所提及的“坑”,因为这种方法奇偶性的判定完毕之后,直接和逆序之前的奇偶性是相反的(循环变量从左往右,从0开始,才有相反这个结论。如果从1开始,则奇偶性相同。主要还是和题目本身的奇偶性对应起来考虑即可。)。 比如:现在的从左往右第一位开始时i=0,i是偶数,而这一位本来应该是奇数位才对,因为这一位对应的是逆序前从右往左的左后一位。(似乎有点绕,需仔细思考)
这个算法主要就是数组逆序的实现,之后就和第一种思路的实现大同小异,暂时不贴代码了。