训练思维的题目——考卷问题

训练思维的题目——考卷问题

题目:

学校进行了一次考试,共有10道是非题,每题为10分,解答用1表示“是”,用0表示“非”的方式。但老师批完卷后,发现漏批了一张试卷,而且标准答案也丢失了,手头只剩下了3张标有分数的试卷。
试卷一:
①   ②   ③   ④   ⑤   ⑥   ⑦   ⑧   ⑨   ⑩
0     0     1    0     1    0    0     1    0     0      得分:70
试卷二:
①   ②   ③   ④   ⑤   ⑥   ⑦   ⑧   ⑨   ⑩
0     1    1     1    0     1    0     1    1     1      得分:50
试卷三:
①   ②   ③   ④   ⑤   ⑥   ⑦   ⑧   ⑨   ⑩
0     1    1     1    0     0    0     1    0     1      得分:30
待批试卷:
①   ②   ③   ④   ⑤   ⑥   ⑦   ⑧   ⑨   ⑩
0     0    1     1    1     0    0     1    1     1      得分:?
请编一程序依据这三张试卷,算出漏批的那张试卷的分数。

 

如果不用程序来做,怎么做?分析下:

对比试卷二 和试卷三,不难发现两份答案不同在⑥ 和⑨,而试卷二比试卷三多了20分,推得这两题目的答案是试卷二为准,即答案:

①   ②   ③   ④   ⑤   ⑥   ⑦   ⑧   ⑨   ⑩

?    ?   ?   ?   ?   1    ?   ?   1    ?

对比试卷一和试卷二,不同的有②④⑤⑥⑨⑩。试卷一⑥⑨都错了,则要求②④⑤⑩都对才满足比试卷二多20分。进一步推得答案:

①   ②   ③   ④   ⑤   ⑥   ⑦   ⑧   ⑨   ⑩

?    0    ?   0     1    1    ?   ?   1     0

试卷一是70分,推出试卷一的①③⑦⑧里面有一个是错的而其他正确(因为⑥ ⑨已经错了,再错一个才满足70分)。

对比待批试卷和试卷一,①③⑦⑧是相同的,也就是待批试卷中,①③⑦⑧题目共得到30分(和试卷一相同),剩下的按照推论出来的便可算分数。参照已知答案,待批试卷 ②④⑤⑥⑨⑩中的②⑤⑨和答案一样,也就是这部分得分也是30分,可以推得待批试卷是60分了。

==============这是一条很漂亮的分割线==================

程序来实现:

试想把答案看作一个二进制排序显示的数字,这个数字有10个bit,其中每个bit 是1或0 就是表示对应位的判断题的是非情况了。所有的情况就是这10个bit的所有情况组合。也就是从0 到 1024-1(2^10-1)的数字二进制方式显示的样式,表示这道试卷答案的所有情况了。一共1024个可能,枚举下出来即可。

假设答案对应的数字N,那么考生提交到试卷为X,那么这个N 和X 有多少个bit 是相同的就是考生答对题目数了(这里N和X均小于1024)。

比如第一份试卷写的为:0 0 1 0 1 0 0 1 0 0 ,把它看成一个数字的二进制显示,那么这个数字N就是164了,同理得试卷二为471(二进制显示为0111010111),第三份是453,待审批的为231。如果标准答案为1111111111(也就是这个N值为1023),那么看看试卷的二进制数字和标准答案的有多少个bit 是相同的就是做对了多少题目了。

很巧,两个数异或操作的结果即计算两个数不同的bit对应的数字,可以用来做该题目的计算不同bit的个数。

代码如下,使用python实现:

#-*- coding: UTF-8 -*-

def get_same_bit_count(a,b):

    x = a^b # x 即为答错的题目对应的数字
    count = 0
    while x > 0:
        count += (x & 1)
        x >>= 1

    return 10 - count
    '''
    和上面逻辑是等价的
    count = 0
    for i in xrange(10):
        if ((a % 2) == (b % 2)):
            count += 1

        a >>= 1
        b >>= 1

    return count
    '''

def answer_str(answer):
    result = ""
    for i in xrange(10):
        result = str(answer & 1) + " " + result
        answer >>= 1

    result = "[ " + result+  "]"
    return result

if __name__ == "__main__":

    possibility = 0

    for i in xrange(1024):
        # 164二进制为 0010100100 也就是试卷1的答案
        if get_same_bit_count(i,164) != 7:
            continue

        # 471二进制为 0111010111 也就是试卷2的答案
        if get_same_bit_count(i,471) != 5:
            continue

        # 164二进制为 0111000101 也就是试卷3的答案
        if get_same_bit_count(i,453) != 3:
            continue

        possibility += 1

        print("答案第" + str(possibility) + "种可能为:" + answer_str(i) +
             ";最后一张试卷得分:" + str(get_same_bit_count(i,231) * 10) + "。")

运行结果:

答案第1种可能为:[ 0 0 0 0 1 1 0 1 1 0 ];最后一张试卷得分:60。
答案第2种可能为:[ 0 0 1 0 1 1 0 0 1 0 ];最后一张试卷得分:60。
答案第3种可能为:[ 0 0 1 0 1 1 1 1 1 0 ];最后一张试卷得分:60。
答案第4种可能为:[ 1 0 1 0 1 1 0 1 1 0 ];最后一张试卷得分:60。

发表评论

电子邮件地址不会被公开。 必填项已用*标注