一、用字典将器件的FUNC转化为数字
二、维护三个数据列表,输入信号列表input_list=[I1, I2, I3, ..., Im],每个器件的输出值列表out_list=[O1, O2, ..., On],器件信息列表unit_list=[(功能号, [输入信号1, ...,输入信号s])]。out_list与unit_list的元素有对应关系。
三、代码运行逻辑为,遍历器件信息列表unit_list,如果有能算的器件,就算出该器件的输出,并写入out_list。遍历器件信息列表若干遍后,所有能算出输出值的器件都会被算出来写到out_list中。根据题目要求查询out_list得到题目要的器件的输出。
四、如何判环?把unit_list遍历一遍,得到一个类似校验码的值,程序中为变量MD5(并不是真的MD5码,就是顺口叫的),若再遍历一遍unit_list,其元素全都没变,表现为MD5值不变,就说明没有可以算的原件了。这时若有原件还是没有被计算过,说明其输入值根本不可得,即有循环。这一点在程序中表现为能算的都算了,out_list中竟然还记录有的原件输出为-1。-1为out_list元素初始值。
五、注意1和0的逻辑运算,~0=-1,~1=-2,要想实现0和1的相互转化应该用not 1=0,not 0=1
mapping={'NOT':0,'AND':1,'OR':2,'XOR':3,'NAND':4,'NOR':5}
Q=int(input().strip())
for q in range(Q):
M,N=map(int,input().strip().split())
unit_list=[]
for i in range(N):
temp=input().strip().split()
ttemp=[]
for j in range(2,len(temp)):
chars=temp[j]
if chars[0]=='I':
ttemp.append(int(chars[1:]))
else:
ttemp.append(-1*int(chars[1:]))
unit_list.append((mapping[temp[0]],ttemp))
S=int(input().strip())
input_list=[]
for i in range(S):
input_list.append(list(map(int,input().strip().split())))
out_index_list=[]
for i in range(S):
out_index_list.append(list(map(int,input().strip().split()[1:])))
out_list=[[-1 for i in range(N)] for j in range(S)]
def cal_able(iindex,epoch):
_,coefs=unit_list[iindex]
for i in coefs:
if i <0 and out_list[epoch][-1*i-1]==-1:
return False
return True
def cal(iindex,nums,epoch):
ttype,_=unit_list[iindex]
if ttype==0:
out_list[epoch][iindex]=int(not nums[0])
elif ttype==1:
temp=1
for num in nums:
temp=temp&num
out_list[epoch][iindex]=temp
elif ttype==2:
temp=0
for num in nums:
temp=temp|num
out_list[epoch][iindex]=temp
elif ttype==3:
temp=nums[0]
for i in range(1,len(nums)):
temp=temp^nums[i]
out_list[epoch][iindex]=temp
elif ttype==4:
temp=1
for num in nums:
temp=temp&num
out_list[epoch][iindex]=int(not temp)
elif ttype==5:
temp=0
for num in nums:
temp=temp|num
out_list[epoch][iindex]=int(not temp)
def calculate(iindex,epoch):
_,coefs = unit_list[iindex]
nums=[]
for i in coefs:
if i>0:
nums.append(input_list[epoch][i-1])
else:
nums.append(out_list[epoch][-1*i-1])
cal(iindex,nums,epoch)
for epoch in range(S):
old_MD5=0
new_MD5=sum(out_list[epoch])
while old_MD5!=new_MD5:
old_MD5=new_MD5
for i in range(len(unit_list)):
if cal_able(i,epoch):
calculate(i,epoch)
new_MD5=sum(out_list[epoch])
dlt=1
for epoch in range(S):
if -1 in out_list[epoch]:
print('LOOP')
dlt=0
break
if dlt:
for epoch in range(S):
for i in out_index_list[epoch]:
print(out_list[epoch][i-1], end=' ')
print()
仍有可以优化的地方,懒得优化了,跑了93ms,还行。
欢迎提建议。