成都东软学院新生周赛(五)
感受
这次比赛打的非常艰辛,全程1.20小时的时间全在写A题,而且还没有写出来。还是自己太菜了。比赛过程中根本就没有想到用位运算去写着三个题。
考点
位运算:位运算是二进制下的运算,运算速度最快,运算级别最低.
C语言中数都是以补码的形式存在的,所以取反的时候要注意这一点(正负数的考虑).
A:找出数组中唯一只出现过一次的数,别个数都出现两次。
在做这个题的时候,根本就没有想到位运算,所以我就把我能用的方法都试了一下,map,排序,暴力。发现都不行。赛后问他们发现这题太水了,一个异或就可以解决的事情。
我们知道异或可以理解为不进位的加法(两个数相加最高位不会改变).但这题关键和不进位没有关系.我们可以发现两个相同的数互相异或的值为0,我们是不是可以把数组中的每个数都异或一次,最后的结果就是我们要的到的数.
B:找出数组中两个只出现过一次的数,别个数都出现两次
这个题和上个题很像,是异或的进击版.还是和上面一样,但是这次我们的出来的值ans = a^b
.显然我们要在这里面得出答案.最后的答案肯定不是0,根据异或的定义,可以知道两个数二进制位不同为1,我们把这一位找出来辅助为flag
,然后运用位运算且,循环遍历整个数组,把每个数与flag比较,如果为真,则用a异或,否则用b异或,这样就可以把两个数独立出来.
C:找出数组中唯一只出现过一次的数,别个数都出现三次(数组大小为3*N+1)
这个题就不好直接的用异或,但是可以借用上面的思想,由于不知道数据的大小,就当成64位的long long来算,我们开始一个大小为65的数组,我们用这个数组来模拟二进制.
将每个数都转换成二进制,并存入数组中,最后我们就得到所有数的二进制情况.我们只需要遍历这个数组,把每一位对3取余,如果不为0,则把这一位转换成10进制存入ans中.
感想
昨天晚上看到题解补完题后,只能说这次不应该报零.还是自己的实力不够,有人AK,有人报零.最近状态一直不在,是要找个时间好好的调整一下了.