蓝桥杯算法训练之审美课(Python)

在这里插入图片描述
刚开始看到这没什么感觉,后来才猛然想到,这不就是用空间换时间了嘛 QAQ
在这里插入图片描述
在这里插入图片描述
做这道题时,由于本人算法基础很差,我首先想到的是最直接暴力的方法:用列表生成式生成一个二维数组,然后逐行比较(以样例为例,就是第一行与第二行比较,第一行再与第三行比较,第二行再与第三行比较…)

#判断两个列表是否相反(两个同学的答案是否相反)
def foo(list1,list2):
    p=0
    for i in range(len(list1)):
        p+=1
        if list1[i]==list2[i]:
            p=0
    if p==len(list1):
        return 1
    else :
        return 0
        
n=int(input())
m=int(input())
intlist=[[0 for i in range(m)]for j in range(n)]
for i in range(n):
    for j in range(m):
        x=input()
        intlist[i][j]=x
        
sum=0
for a in range(len(intlist)):
    for b in range(a+1,len(intlist)):
            if foo(intlist[a],intlist[b]):
                sum+=1
print(sum)

这是运行结果:
在这里插入图片描述
好,没事了,美滋滋,提交去:
在这里插入图片描述
???
好吧,想了半天,我终于知道了:输入格式不对…
input()输入完需要回车,但是题目要求是空格,好吧,改代码:

#判断两个列表是否相反(两个同学的答案是否相反)
def foo(list1,list2):
    p=0
    for i in range(len(list1)):
        p+=1
        if list1[i]==list2[i]:
            p=0
    if p==len(list1):
        return 1
    else :
        return 0
        
###改动部分
n,m=map(int,input().split())
intlist=[[0 for i in range(m)]for j in range(n)]
#由于是电脑自动测试,所以我就没管m,没有去关心那些数组越界什么的...
for i in range(n):
    slist=[]
    slist=list(map(int,input().split()))
    intlist[i]=slist
###

sum=0
for a in range(len(intlist)):
    for b in range(a+1,len(intlist)):
            if foo(intlist[a],intlist[b]):
                sum+=1
print(sum)

再看运行结果:
在这里插入图片描述
美滋滋,再去提交一遍:
在这里插入图片描述
???///…只有30,也就是说10个测试只有三个出结果且没超时。。。
不过想想也正常,这种方法数据量大了,无效对比太多,肯定会超时。

后来看到了一篇大佬的博客,用二进制搞,嗯,大佬就是大佬。
上代码(我把思路注释在里面了):

n, m = map(int, input().split())
d = {}
for i in range(n):
    num = 0
    x = input().split()
    for j in x:
        num = (num << 1) + int(j)
    d[num] = d.get(num, 0) + 1
'''
以样例输入为例:
输入1 0 -> 00000010为2 -> num=2
输入0 1 -> 00000001为1 -> num=1
输入1 0 -> 00000010为2 -> num=2
0 0:0; 0 1:1; 1 0:2; 1 1:3
d[num]={2: 2, 1: 1} /// {答案为*的同学:有几个人}
即答案相同(1 0)的同学有两个
另一个同学答案不同为(0 1)
'''
sum = 0
max = (1 << m) - 1
'''
max为画数
<<几就是*2的几次方
'''
mid = max // 2
for i in d:
    if max < i:
    # if mid <i:
        continue
    sum += d[i] * d.get(max ^ i, 0) 
print(int(sum/2))
# print(sum)
'''
max^i:按位取反,简化判断
d.get(max ^ i, 0) 即获得与答案为i的同学相反的人数
'''

在这里插入图片描述
嗯,妥妥的。

发布了20 篇原创文章 · 获赞 10 · 访问量 1232

猜你喜欢

转载自blog.csdn.net/qq_43613793/article/details/103055635
今日推荐