21计科程一帆


私信TA

用户名:uq_88617846948

访问量:5230

签 名:

搞哥毛哥在上,俺寻思俺是一个最大最强的技术小子

等  级
排  名 959
经  验 3415
参赛次数 2
文章发表 52
年  龄 19
在职情况 学生
学  校 石河子大学
专  业 计算机科学与技术

  自我简介:

憨憨一个,欢迎大佬指正

题目见于:116. 飞行员兄弟 - AcWing题库

本题目的C++/Java解法较多,我自己搜索python题解的时候搜索不到,这里给大家伙介绍一种python的不超时写法:

  本题目中已要求有16开关,每一个开关的状态都可以有两种,那么复杂度最多2^16=65536,暴力搜索一定程度上可行,但是不能完全暴力搜索,在遍历每一种情况的时候可以取点巧,比如用0-65535的每一个数的二进制中的1所处位置的的序号来表示该种情况下哪一个开关被打开了,然后记录被打开开关的个数以及坐标,再判断该种情况是否符合最后要求的全打开的结果,符合则用新变量res记录,当遇到新的解决方案,同时该方案需要的步数更短的时候,更新res,该题目中要求同样步数的情况下优先记录自上而下,自左而右的结果,因此我们这里使用0-65535二进制表示每一种情况的做法是正确的,因为二进制数越小的情况下,其数位中所有”1“的位置越靠前,即按动开关的步数也就更加符合题目优先顺序。


具体代码如下:

def turnone(a):
   if a=="+":
       return "-"
   else:
       return "+"


def turnall(b,c):
   for i in range(4):
       h[i][c]=turnone(h[i][c])
       h[b][i]=turnone(h[b][i])
   h[b][c]=turnone(h[b][c])


h=[[" "]*4 for _ in range(4)]


for i in range(4):
   row=list(input())
   for j in range(len(row)):
       h[i][j]=row[j]


back=[fuzhi[:] for fuzhi in h]
res=[]


for op in range(1<<16):
   temp = []
   for i in range(4):
       for j in range(4):
           if(op>>(4*i+j))&1:
               turnall(i,j)
               temp.append((i,j))
   flag=0
   for k in range(4):
       for l in range(4):
           if h[k][l]=="+":
               flag=1
               break
   if  flag==0:
       if not res or len(res)>len(temp):
           res=temp
   h=[fuzhi1[:] for fuzhi1 in back]


print(len(res))
for i in res:
   print(i[0]+1,i[1]+1,sep=" ")

 

0.0分

1 人评分

  评论区

  • «
  • »