连连看之Golang版本

连连看是一种很受大家欢迎的小游戏。下面四张图给出了最基本的消除规则:


图 A 中出现在同一直线上无障碍的圈圈可以消除;图 B 中两个圈圈可以通过一次转弯消除;图 C 和图 D 中,两个圈圈可以通过两次转弯消除。

首先需要判断路上是否有障碍物

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

判断是否是图A的情况,则需要判断水平或者竖直是否能直接联通

/检测水平之间是否联通
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
}
//竖直是否联通
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
//单个拐角之间是否能联通
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 的点,看是否存在一点 C ,满足以下任意一项:

A 点至 C 点通过水平或垂直检测,C 点至 B 点可通过一个拐角连接。(图中用 C 表示)
A 点至 C 点可通过一个拐角连接,C 点至 B 点通过水平或垂直连接。(图中用 C 下划线表示)

//两个拐角是否能联通
//两个拐角意思就是一个水品或者垂直到一个中间点,又能拐角到另一个点
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{//不在两点的水平或者垂直线上
                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
}

//检测水平之间是否联通
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
}
//竖直是否联通
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
//单个拐角之间是否能联通
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
}
//两个拐角是否能联通
//两个拐角意思就是一个水品或者垂直到一个中间点,又能拐角到另一个点
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{//不在两点的水平或者垂直线上
                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
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358

推荐阅读更多精彩内容

  • 高级钳工应知鉴定题库(858题) ***单选题*** 1. 000003难易程度:较难知识范围:相关4 01答案:...
    开源时代阅读 5,795评论 1 9
  • 1. 下列叙述错误的是()。 (2.0 分) A. 质量管理包括QA和QC一切活动的全部过程 B. 影像质量是指对...
    我们村我最帅阅读 3,835评论 0 8
  • 选择题部分 1.()部门负责日常监督检查工作,安全巡视的同时进行消防检查,推动消防安全制度的贯彻落实。 A: 消防...
    skystarwuwei阅读 15,259评论 0 3
  • 1. 关于诊断X线机准直器的作用,错误的是()。 (6.0 分) A. 显示照射野 B. 显示中心线 C. 屏蔽多...
    我们村我最帅阅读 10,499评论 0 5
  • 选择题部分 1.(),只有在发生短路事故时或者在负荷电流较大时,变流器中才会有足够的二次电流作为继电保护跳闸之用。...
    skystarwuwei阅读 12,954评论 0 7