1048 数字加密 (20 point(s))

时间:2021-09-01
本文章向大家介绍1048 数字加密 (20 point(s)),主要包括1048 数字加密 (20 point(s))使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
// 错误魔改后正确版
#include <bits/stdc++.h>
using namespace std;

int main() {
	// 加密整数A 加密序列B
	string A, B, str = "0123456789JQK" ;
	cin >> A >> B;
	
	// 高位补零 
	// 获取A比B多出来的位数并转换为下标 
	for( int i = A.size() - B.size() - 1; i >= 0; i--){
		B.insert(0, 1, '0'); 
	}
	int flag = 1;
	// 右向左为高位 个位第一位 	
	for(int i = A.size() - 1, j = B.size() - 1; i >= 0 && j >= 0; i--, j--){

		// 每位数字 与A对应位置运算
		// A奇数位置 相加后 13取余 J 10 Q 11 K 12
		if(flag){
			flag = 0;
			// 直接替换B位置元素
			int tmp = (int)(A[i] + B[j] - 2 * '0') % 13;
			B[j] = str[tmp];
		}
		// 偶数 B 减去A  结果为负再加 10
		else{
			flag = 1;
			int tmp = B[j] - A[i];
			if(tmp < 0) tmp += 10;
			B[j] = tmp + '0';
		} 
	}
	cout << B;
}
}

原来少考虑了一种情况。原本的想法是照着样例给出的一种条件,当 B 长于 A 的时候,高位 B 可以直接输出。所以最开始写的时候,仅仅只是考虑了 B > A 的时候。

并且最开始连 “与A对应位置运算” 这个条件也没有正确理解。以为左边才是对应的位置,从左边向右边一一对应。但结合另一个条件 “个位为第 1 位”,实际应该是从右边到左边为低位到高位,从右到左一一对应。

换句话来说就是左对齐和右对齐的区别,而这里则是右对齐。

所以这两个理解不正确,导致对 A < B 的时候没能够正确理解,同时因为没有正确位置上高位补零,导致卡测试点2。


学别人补零之后反而卡了测试点零、四五。结果一个个排除居然是奇偶位置判断的问题。

因为刚开始是照着题目要求判断奇偶位置的,结果发现由于下标会 - 1,导致用下标判断的话会导致奇偶结果互换。所以就从 i % 2 == 1 改成 i % 2 == 0 为奇数。

但这反而会导致测试点4和5的错误。最后学别人用flag记录,输出一个换一个处理方法,才能全部AC。

但还是不太理解,为什么会有这样的错误,难道奇偶不是隔一个出现?为什么会出现这样写判断会有问题?


不过看别人的代码,如果从屁股开始遍历的话,也可以用用 reverse() 函数将字符串倒置,而可以从 i = 0 开始遍历。

而这样写,就可以用 i & 2 来判断奇偶。真是神秘。

参考代码1


参考别人还学到两个东西,一个是关于字符数组比如

char str[13] = { '0','1','2','3','4','5','6','7','8','9','J','Q','K' };

可以写成

string str = "0123456789JQK";

这样就不需要写这么多 '' 了,使用上也是一致的。

还有就是字符串的拼接,原本以为是Java的,原来C++也可以实现这么方便的操作。比如别人高位补零的是这样写的。

while (A.size() < B.size()) { A = '0' + A; }
while (A.size() > B.size()) { B = '0' + B; }

参考代码2


写的时候注意的,关于数字字符的运算后转换成数字的问题。

如果是两个数字字符相加的时候,需要减去两个 '0',才能转换成真正的数字。

而相减的时候,因为数字字符本身带有 '0' ,所以相减的时候直接就减去了,直接就转换成真正的数字,不需要额外加减 '0'。

原文地址:https://www.cnblogs.com/Atl212/p/15215045.html