Day 2 熄燈問題
規則是 0 表示燈的狀態爲亮,1表示燈的狀態爲滅,然後有一個開關矩陣 1表示按下 0表示無操作,如果原來的燈亮 則按下去之後 燈就滅了,反之亦然。
只不過按下開關操作的並不僅僅是被按下的燈,還會影響它周圍燈的狀態,也就是中間的燈來說 會造成5個(上下左右和本身)燈狀態的改變,對於四個角上的燈只有三個狀態改變,對於邊上的燈會有4個狀態發生改變。
現在假設有一批燈 5*6的矩陣存着該燈的狀態,然後還有一個開關矩陣 存着對這批燈的相應操作,問對於某一批燈的狀態 應該選擇按下哪幾個開關的,會使得這批燈全部熄滅。
具體思路
由於中間的燈和四個角以及邊上燈的操作不一樣 所以我們需要把5*6的矩陣擴展乘6*8的矩陣 這樣對於所有的燈操作都一樣啦,而且此時開關矩陣也就變成6*8的啦
我們需要用一個status矩陣存儲燈的初始狀態,這需要用戶輸入 然後需要用另一個矩陣存儲對這批燈相應的操作;
我們可以這樣想,給定燈的初始狀態對於每一次判斷,我們只需要對第一行燈操作的開關狀態,第一行燈操作之後 如果要使得第一行等全滅 那麼第二行燈開關的狀態就確定了,等對第二行燈操作結束之後,要使得第二行燈全滅,我們需要操作第三行燈,也就是第三行燈的開關狀態就又確定了,,,以此類推 。
也就是隻要給定第一行的開關狀態,其他行的開關狀態就確定了 (因爲我們的目標是把每一行通過操作開關來滅掉它們)
對於最後一行燈,最後一行燈的開關狀態確定之後,我們通過判斷最後一行燈是否全滅 來確定通過第一行開關狀態確定的其餘各行開關狀態是否合理 ,如果不是全滅 就說明第一行選取的開關狀態不合理需要重新選擇。
這裏對於第一行開關狀態的選擇是根據二進制的規則進行的,這段程序我寫的不好,以後有思路了再來改,,,,
接下來直接上代碼:
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 23 16:29:59 2018
@author: xuanxuan
"""
#這一題主要求解熄燈問題
#狀態矩陣 0表示燈亮 1表示燈滅;
#按壓矩陣 0表示不按壓 1表示對應位置的燈按下去
#所以要使得燈是滅的 需要該燈的狀態值+周圍可以影響到它的press值 加起來是1,3,, 奇數纔可以
import numpy as np
def get_status():
status=np.mat(np.zeros((6,8))) #初始化該狀態矩陣 主要是前面用不到的寫0就行
for i in range(1,6):
for j in range(1,7):
status[i,j]=eval(input("please input:")) #主要是對初始化的矩陣 重新賦值 該status矩陣表示燈的最初始狀態
print(status)
return status
#get_status()
#負責不斷的更新press矩陣的第一行
def update_firstpress(status):
press=np.mat(np.zeros((6,8)))
value=[0]*8 #初始化press矩陣的第一行,主要是方便更新press第一行所寫的
while(judge(status,press)==False):
value[0]+=1
if value[0]>=2:
value[0]=0
value[1]+=1
if value[1]>=2:
value[1]=0
value[2]+=1
if value[2]>=2:
value[2]=0
value[3]+=1
if value[3]>=2:
value[3]=0
value[4]+=1
if value[4]>=2:
value[4]=0
value[5]+=1
if value[5]>=2:
value[5]=0
value[6]+=1
if value[6]>=2:
value[6]=0
value[7]+=1
press[1]=np.mat(value)
#根據狀態矩陣 和press矩陣的第一行 不斷生成後續的press 下一行的perss主要是爲了滅掉上一行的燈
#然後根據最後一行的狀態以及最後一行press按壓之後的效果能否使得最後一行的燈滅掉
#來判斷該press矩陣是否對現有的燈狀態 全部滅掉
#負責根據press矩陣的第press[1]行(當然需要知道press[0]行)來更新press矩陣其餘各行
def judge(status,press):
for i in range(1,5):
for j in range(1,7):
if (status[i,j]+press[i-1,j]+press[i,j-1]+press[i,j]+press[i,j+1])%2==1:
press[i+1,j]=0 #也就是對於該燈來說 其狀態 以及周圍燈(不包括下一行的 也就是位於其正下方的燈)對其的影響已經使得該燈滅了 所以下一行的燈 的press 一定是爲0 就是不操作了不在按壓
else:
press[i+1,j]=1
#以上就對傳入的press矩陣不改變0 1 行的情況下 其實就是根據第[1]行不斷的更新其餘矩陣
for k in range(1,8):
if (status[5,j]+press[4,j]+press[5,j-1]+press[5,j]+press[5,j+1])%2==0:
return False
print("滿足條件的press矩陣爲:\n{}".format(press))
return True
if __name__=="__main__":
status=get_status()
update_firstpress(status)
這一題的實現我真的是想了好久,,主要就是二進制手動生成那塊,最後也沒想出來,,,隨便用了一個笨方法,,,嗚嗚嗚,,,
明天也要加油鴨~~~
以上。