python算法題記錄(二)

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)    


這一題的實現我真的是想了好久,,主要就是二進制手動生成那塊,最後也沒想出來,,,隨便用了一個笨方法,,,嗚嗚嗚,,,

明天也要加油鴨~~~

以上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章