連連看之Golang版本

連連看是一種很受大家歡迎的小游戲。下面四張圖給出了最基本的消除規(guī)則:


圖 A 中出現(xiàn)在同一直線上無障礙的圈圈可以消除;圖 B 中兩個圈圈可以通過一次轉(zhuǎn)彎消除;圖 C 和圖 D 中,兩個圈圈可以通過兩次轉(zhuǎn)彎消除。

首先需要判斷路上是否有障礙物

func isBlocked(full [][]byte,i,j int)bool  {
    if full[i][j]=='.'{
        return false
    }
    return true
}

判斷是否是圖A的情況,則需要判斷水平或者豎直是否能直接聯(lián)通

/檢測水平之間是否聯(lián)通
func horizon(full [][]byte,x1,y1,x2,y2 int)bool  {
    if x1==x2&&y1==y2{
        return false
    }
    if x1!=x2{
        return false
    }
    start := min(y1,y2)
    end := max(y1,y2)

    for j:=start+1;j<end;j++{
        if isBlocked(full,x1,j){
            return false
        }
    }
    return true
}
//豎直是否聯(lián)通
func vertical(full [][]byte,x1,y1,x2,y2 int)bool{
    if x1==x2&&y1==y2{
        return false
    }
    if y1!=y2{
        return false
    }
    start := min(x1,x2)
    end := max(x1,x2)

    for j:=start+1;j<end;j++{
        if isBlocked(full,j,y1){
            return false
        }
    }
    return true
}

判斷圖B的情況,即如下圖所示


能A-C豎直+C-B水平
或者A-D水平,D-B豎直

//C           B(x2,y2)
//A(x1,y1)    D
//單個拐角之間是否能聯(lián)通
func sigTurn(full [][]byte,x1,y1,x2,y2 int)bool {
    if x1==x2&&y1==y2{
        return false
    }
    c_x,c_y := x2,y1
    d_x,d_y := x1,y2
    var ret bool
    if !isBlocked(full,c_x,c_y){
        ret = ret||(horizon(full,x1, y1, c_x, c_y) && vertical(full,c_x, c_y, x2, y2))
    }
    if !isBlocked(full,d_x,d_y){
        ret = ret||(horizon(full,x1, y1, d_x, d_y) && vertical(full,d_x, d_y, x2, y2))
    }
    return ret
}

判斷圖C和圖D的情況

兩個拐角檢測 = 一個拐角檢測 && (水平檢測 || 垂直檢測)



如圖,水平、垂直分別穿過 A B 共有四條直線,掃描直線上所有不包含 A B 的點(diǎn),看是否存在一點(diǎn) C ,滿足以下任意一項:

A 點(diǎn)至 C 點(diǎn)通過水平或垂直檢測,C 點(diǎn)至 B 點(diǎn)可通過一個拐角連接。(圖中用 C 表示)
A 點(diǎn)至 C 點(diǎn)可通過一個拐角連接,C 點(diǎn)至 B 點(diǎn)通過水平或垂直連接。(圖中用 C 下劃線表示)

//兩個拐角是否能聯(lián)通
//兩個拐角意思就是一個水品或者垂直到一個中間點(diǎn),又能拐角到另一個點(diǎn)
func twoTurn(full [][]byte,x1,y1,x2,y2 int)bool {
    if x1==x2&&y1==y2{
        return false
    }
    l1 := len(full)
    l2 := len(full[0])
    for i:=0;i<l1;i++{
        for j:=0;j<l2;j++{
            if i!=x1&&i!=x2&&j!=y1&&j!=y2{//不在兩點(diǎn)的水平或者垂直線上
                continue
            }
            if (i==x1&&j==y1)||(i==x2&&j==y2){
                continue
            }
            if isBlocked(full,i,j){
                continue
            }
            if sigTurn(full,x1,y1,i,j)&&(horizon(full,x1,y1,i,j)||vertical(full,x1,y1,i,j)){
                return true
            }
            if sigTurn(full,i,j,x2,y2)&&(horizon(full,i,j,x2,y2)||vertical(full,i,j,x2,y2)){
                return true
            }
        }
    }
    return false
}

附上完整代碼


package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    var m,n int
    fmt.Scanf("%d %d",&m,&n)
    var qipan = make([][]byte,0)
    bfio := bufio.NewReader(os.Stdin)
    for i:=0;i<m;i++{
        tmp,_:=bfio.ReadBytes('\n')
        qipan = append(qipan,tmp)
    }
    fmt.Println(qipan)
    var op int
    fmt.Scanf("%d",&op)
    for i:=0;i<op;i++{
        var x1,y1,x2,y2 int
        fmt.Scanf("%d %d %d %d",&x1,&y1,&x2,&y2)
        if qipan[x1-1][y1-1]==qipan[x2-1][y2-1]&&remove(qipan,x1-1,y1-1,x2-1,y2-1){
            fmt.Println("YES")
        }else {
            fmt.Println("NO")
        }
    }

}

func remove(full [][]byte,x1,y1,x2,y2 int)bool{
    var ret bool
    ret = horizon(full,x1,y1,x2,y2)
    if ret{
        full[x1][y1],full[x2][y2] = '.','.'
        return true
    }
    ret = vertical(full,x1,y1,x2,y2)
    if ret{
        full[x1][y1],full[x2][y2] = '.','.'
        return true
    }
    ret = sigTurn(full,x1,y1,x2,y2)
    if ret{
        full[x1][y1],full[x2][y2] = '.','.'
        return true
    }
    ret = twoTurn(full,x1,y1,x2,y2)
    if ret{
        full[x1][y1],full[x2][y2] = '.','.'
        return true
    }
    return false
}

func isBlocked(full [][]byte,i,j int)bool  {
    if full[i][j]=='.'{
        return false
    }
    return true
}

//檢測水平之間是否聯(lián)通
func horizon(full [][]byte,x1,y1,x2,y2 int)bool  {
    if x1==x2&&y1==y2{
        return false
    }
    if x1!=x2{
        return false
    }
    start := min(y1,y2)
    end := max(y1,y2)

    for j:=start+1;j<end;j++{
        if isBlocked(full,x1,j){
            return false
        }
    }
    return true
}
//豎直是否聯(lián)通
func vertical(full [][]byte,x1,y1,x2,y2 int)bool{
    if x1==x2&&y1==y2{
        return false
    }
    if y1!=y2{
        return false
    }
    start := min(x1,x2)
    end := max(x1,x2)

    for j:=start+1;j<end;j++{
        if isBlocked(full,j,y1){
            return false
        }
    }
    return true
}
//C           B(x2,y2)
//A(x1,y1)    D
//單個拐角之間是否能聯(lián)通
func sigTurn(full [][]byte,x1,y1,x2,y2 int)bool {
    if x1==x2&&y1==y2{
        return false
    }
    c_x,c_y := x2,y1
    d_x,d_y := x1,y2
    var ret bool
    if !isBlocked(full,c_x,c_y){
        ret = ret||(horizon(full,x1, y1, c_x, c_y) && vertical(full,c_x, c_y, x2, y2))
    }
    if !isBlocked(full,d_x,d_y){
        ret = ret||(horizon(full,x1, y1, d_x, d_y) && vertical(full,d_x, d_y, x2, y2))
    }
    return ret
}
//兩個拐角是否能聯(lián)通
//兩個拐角意思就是一個水品或者垂直到一個中間點(diǎn),又能拐角到另一個點(diǎn)
func twoTurn(full [][]byte,x1,y1,x2,y2 int)bool {
    if x1==x2&&y1==y2{
        return false
    }
    l1 := len(full)
    l2 := len(full[0])
    for i:=0;i<l1;i++{
        for j:=0;j<l2;j++{
            if i!=x1&&i!=x2&&j!=y1&&j!=y2{//不在兩點(diǎn)的水平或者垂直線上
                continue
            }
            if (i==x1&&j==y1)||(i==x2&&j==y2){
                continue
            }
            if isBlocked(full,i,j){
                continue
            }
            if sigTurn(full,x1,y1,i,j)&&(horizon(full,x1,y1,i,j)||vertical(full,x1,y1,i,j)){
                return true
            }
            if sigTurn(full,i,j,x2,y2)&&(horizon(full,i,j,x2,y2)||vertical(full,i,j,x2,y2)){
                return true
            }
        }
    }
    return false
}

func max(i,j int)int  {
    if i > j{
        return i
    }
    return j
}

func min(i,j int)int  {
    if i < j{
        return i
    }
    return j
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 高級鉗工應(yīng)知鑒定題庫(858題) ***單選題*** 1. 000003難易程度:較難知識范圍:相關(guān)4 01答案:...
    開源時代閱讀 6,295評論 1 9
  • 1. 下列敘述錯誤的是()。 (2.0 分) A. 質(zhì)量管理包括QA和QC一切活動的全部過程 B. 影像質(zhì)量是指對...
    我們村我最帥閱讀 4,396評論 0 8
  • 選擇題部分 1.()部門負(fù)責(zé)日常監(jiān)督檢查工作,安全巡視的同時進(jìn)行消防檢查,推動消防安全制度的貫徹落實。 A: 消防...
    skystarwuwei閱讀 15,940評論 0 3
  • 1. 關(guān)于診斷X線機(jī)準(zhǔn)直器的作用,錯誤的是()。 (6.0 分) A. 顯示照射野 B. 顯示中心線 C. 屏蔽多...
    我們村我最帥閱讀 11,403評論 0 5
  • 選擇題部分 1.(),只有在發(fā)生短路事故時或者在負(fù)荷電流較大時,變流器中才會有足夠的二次電流作為繼電保護(hù)跳閘之用。...
    skystarwuwei閱讀 14,364評論 0 7

友情鏈接更多精彩內(nèi)容