Golang每日一练(leetDay0098) 生命、Nim、猜数字游戏

news2024/10/7 18:26:29

目录

289. 生命游戏 Game Of Life

292. Nim 游戏 Nim Game

299. 猜数字游戏 Bulls and Cows

🌟 每日一练刷题专栏 🌟

Rust每日一练 专栏

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


289. 生命游戏 Game Of Life

生命游戏  是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞 (dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

  1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
  2. 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
  3. 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
  4. 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;

下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。给你 m x n 网格面板 board 的当前状态,返回下一个状态。

示例 1:

输入:board = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]

示例 2:

输入:board = [[1,1],[1,0]]
输出:[[1,1],[1,1]]

提示:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 25
  • board[i][j] 为 0 或 1

进阶:

  • 你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
  • 本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?

代码1:原地算法

package main

import "fmt"

func gameOfLife(board [][]int) {
	m, n := len(board), len(board[0])
	dirs := [][]int{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			count := 0
			for _, d := range dirs {
				x, y := i+d[0], j+d[1]
				if x >= 0 && x < m && y >= 0 && y < n {
					if board[x][y] == 1 || board[x][y] == 2 {
						count++
					}
				}
			}
			if board[i][j] == 1 && (count < 2 || count > 3) {
				board[i][j] = 2
			} else if board[i][j] == 0 && count == 3 {
				board[i][j] = 3
			}
		}
	}
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			if board[i][j] == 2 {
				board[i][j] = 0
			} else if board[i][j] == 3 {
				board[i][j] = 1
			}
		}
	}
}

func Array2DToString(array [][]int) string {
	if len(array) == 0 {
		return "[]"
	}
	arr2str := func(arr []int) string {
		res := "["
		for i, ar := range arr {
			res += fmt.Sprint(ar)
			if i != len(arr)-1 {
				res += ","
			}
		}
		return res + "]"
	}
	res := "["
	for i, arr := range array {
		res += arr2str(arr)
		if i != len(array)-1 {
			res += ","
		}
	}
	return res + "]"
}

func main() {
	board := [][]int{{0, 1, 0}, {0, 0, 1}, {1, 1, 1}, {0, 0, 0}}
	gameOfLife(board)
	fmt.Println(Array2DToString(board))

	board = [][]int{{1, 1}, {1, 0}}
	gameOfLife(board)
	fmt.Println(Array2DToString(board))
}

输出:

[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]
[[1,1],[1,1]]

代码2:使用额外的数组

package main

import "fmt"

func gameOfLife(board [][]int) {
    m, n := len(board), len(board[0])
    dirs := [][]int{{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}
    newBoard := make([][]int, m)
    for i := 0; i < m; i++ {
        newBoard[i] = make([]int, n)
        copy(newBoard[i], board[i])
    }
    for i := 0; i < m; i++ {
        for j := 0; j < n; j++ {
            count := 0
            for _, d := range dirs {
                x, y := i+d[0], j+d[1]
                if x >= 0 && x < m && y >= 0 && y < n {
                    count += board[x][y]
                }
            }
            if board[i][j] == 1 {
                if count < 2 || count > 3 {
                    newBoard[i][j] = 0
                }
            } else {
                if count == 3 {
                    newBoard[i][j] = 1
                }
            }
        }
    }
    for i := 0; i < m; i++ {
        copy(board[i], newBoard[i])
    }
}

func Array2DToString(array [][]int) string {
	if len(array) == 0 {
		return "[]"
	}
	arr2str := func(arr []int) string {
		res := "["
		for i, ar := range arr {
			res += fmt.Sprint(ar)
			if i != len(arr)-1 {
				res += ","
			}
		}
		return res + "]"
	}
	res := "["
	for i, arr := range array {
		res += arr2str(arr)
		if i != len(array)-1 {
			res += ","
		}
	}
	return res + "]"
}

func main() {
	board := [][]int{{0, 1, 0}, {0, 0, 1}, {1, 1, 1}, {0, 0, 0}}
	gameOfLife(board)
	fmt.Println(Array2DToString(board))

	board = [][]int{{1, 1}, {1, 0}}
	gameOfLife(board)
	fmt.Println(Array2DToString(board))
}

代码3:使用缓存历史状态

package main

import (
	"fmt"
	"strconv"
)

func gameOfLife(board [][]int) {
	m, n := len(board), len(board[0])
	dirs := [][]int{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}
	cache := make(map[string][]int)
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			count := 0
			for _, d := range dirs {
				x, y := i+d[0], j+d[1]
				if x >= 0 && x < m && y >= 0 && y < n {
					count += board[x][y]
				}
			}
			pos := strconv.Itoa(i) + "," + strconv.Itoa(j)
			if count < 2 || count > 3 {
				cache[pos] = []int{0}
			} else if count == 3 {
				cache[pos] = []int{1}
			} else {
				cache[pos] = []int{board[i][j]}
			}
		}
	}
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			pos := strconv.Itoa(i) + "," + strconv.Itoa(j)
			if state, ok := cache[pos]; ok {
				board[i][j] = state[0]
			}
		}
	}
}

func Array2DToString(array [][]int) string {
	if len(array) == 0 {
		return "[]"
	}
	arr2str := func(arr []int) string {
		res := "["
		for i, ar := range arr {
			res += fmt.Sprint(ar)
			if i != len(arr)-1 {
				res += ","
			}
		}
		return res + "]"
	}
	res := "["
	for i, arr := range array {
		res += arr2str(arr)
		if i != len(array)-1 {
			res += ","
		}
	}
	return res + "]"
}

func main() {
	board := [][]int{{0, 1, 0}, {0, 0, 1}, {1, 1, 1}, {0, 0, 0}}
	gameOfLife(board)
	fmt.Println(Array2DToString(board))

	board = [][]int{{1, 1}, {1, 0}}
	gameOfLife(board)
	fmt.Println(Array2DToString(board))
}

292. Nim 游戏 Nim Game

你和你的朋友,两个人一起​ 玩 Nim 游戏:

  • 桌子上有一堆石头。
  • 你们轮流进行自己的回合, 你作为先手 
  • 每一回合,轮到的人拿掉 1 - 3 块石头。
  • 拿掉最后一块石头的人就是获胜者。

假设你们每一步都是最优解。请编写一个函数,来判断你是否可以在给定石头数量为 n 的情况下赢得游戏。如果可以赢,返回 true;否则,返回 false 。

示例 1:

输入:n = 4
输出:false 
解释:以下是可能的结果:
1. 移除1颗石头。你的朋友移走了3块石头,包括最后一块。你的朋友赢了。
2. 移除2个石子。你的朋友移走2块石头,包括最后一块。你的朋友赢了。
3.你移走3颗石子。你的朋友移走了最后一块石头。你的朋友赢了。
在所有结果中,你的朋友是赢家。

示例 2:

输入:n = 1
输出:true

示例 3:

输入:n = 2
输出:true

提示:

  • 1 <= n <= 2^31 - 1

 代码:

package main

import "fmt"

func canWinNim(n int) bool {
    if n <= 3 {
        return true
    }
    dp := make([]bool, n+1)
    dp[1] = true
    dp[2] = true
    dp[3] = true
    for i := 4; i <= n; i++ {
        dp[i] = !(dp[i-1] && dp[i-2] && dp[i-3])
    }
    return dp[n]
}

func main() {
    fmt.Println(canWinNim(4)) // false
    fmt.Println(canWinNim(1)) // true
    fmt.Println(canWinNim(2)) // true
}

输出:

false
true
true

本题的数学本质:

假设当前共有 n 块石头,每次可以拿 1-3 块石头,然后轮到对手。

当 n <= 3 时,先手必胜;当 n = 4 时,先手拿 1 块石头,无论对手拿几块,都会剩下 3 块石头留给先手,此时先手必胜;当 n = 5 时,先手拿 2 块石头,无论对手拿几块,都会剩下 3 块石头留给先手,此时先手必胜;同理,当 n = 6 时,无论先手拿几块,都会剩下 5 块,对手依然可以通过上述策略获胜。

推广到一般情况,当 n 为 4 的倍数时,先手必败,否则必胜。

func canWinNim(n int) bool {

    return n % 4 != 0

}


299. 猜数字游戏 Bulls and Cows

你在和朋友一起玩 猜数字(Bulls and Cows)游戏,该游戏规则如下: ​

写出一个秘密数字,并请朋友猜这个数字是多少。朋友每猜测一次,你就会给他一个包含下述信息的提示:

  • 猜测数字中有多少位属于数字和确切位置都猜对了(称为 "Bulls",公牛),
  • 有多少位属于数字猜对了但是位置不对(称为 "Cows",奶牛)。也就是说,这次猜测中有多少位非公牛数字可以通过重新排列转换成公牛数字。

给你一个秘密数字 secret 和朋友猜测的数字 guess ,请你返回对朋友这次猜测的提示。

提示的格式为 "xAyB" ,x 是公牛个数, y 是奶牛个数,A 表示公牛,B 表示奶牛。

请注意秘密数字和朋友猜测的数字都可能含有重复数字。

示例 1:

输入:secret = "1807", guess = "7810"
输出:"1A3B"
解释:数字和位置都对(公牛)用 '|' 连接,数字猜对位置不对(奶牛)的采用斜体加粗标识。
"1807"
  |
"7810"

示例 2:

输入:secret = "1123", guess = "0111"
输出:"1A1B"
解释:数字和位置都对(公牛)用 '|' 连接,数字猜对位置不对(奶牛)的采用斜体加粗标识。
"1123"        "1123"
  |      or     |
"0111"        "0111"
注意,两个不匹配的 1 中,只有一个会算作奶牛(数字猜对位置不对)。通过重新排列非公牛数字,其中仅有一个 1 可以成为公牛数字。

提示:

  • 1 <= secret.length, guess.length <= 1000
  • secret.length == guess.length
  • secret 和 guess 仅由数字组成

代码1:数组

package main

import (
	"fmt"
	"strconv"
)

func getHint(secret string, guess string) string {
	bulls, cows := 0, 0
	sCount, gCount := [10]int{}, [10]int{}
	for i := 0; i < len(secret); i++ {
		if secret[i] == guess[i] {
			bulls++
		} else {
			sCount[secret[i]-'0']++
			gCount[guess[i]-'0']++
		}
	}
	for i := 0; i < 10; i++ {
		cows += min(sCount[i], gCount[i])
	}
	return strconv.Itoa(bulls) + "A" + strconv.Itoa(cows) + "B"
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func main() {
	fmt.Println(getHint("1807", "7810"))
	fmt.Println(getHint("1123", "0111"))
}

代码2:哈希表

package main

import (
	"fmt"
	"strconv"
)

func getHint(secret string, guess string) string {
    bulls, cows := 0, 0
    count := make(map[byte]int)
    for i := 0; i < len(secret); i++ {
        if secret[i] == guess[i] {
            bulls++
        } else {
            count[secret[i]]++
        }
    }
    for i := 0; i < len(guess); i++ {
        if secret[i] != guess[i] {
            if count[guess[i]] > 0 {
                cows++
                count[guess[i]]--
            }
        }
    }
    return strconv.Itoa(bulls) + "A" + strconv.Itoa(cows) + "B"
}

func main() {
	fmt.Println(getHint("1807", "7810"))
	fmt.Println(getHint("1123", "0111"))
}

输出:

1A3B
1A1B


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.csdn.net/ 

Rust每日一练 专栏

(2023.5.16~)更新中...

Golang每日一练 专栏

(2023.3.11~)更新中...

Python每日一练 专栏

(2023.2.18~2023.5.18)暂停更

C/C++每日一练 专栏

(2023.2.18~2023.5.18)暂停更

Java每日一练 专栏

(2023.3.11~2023.5.18)暂停更

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/651860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

牛客小白月赛56

今天无聊vp了一下 A.省略 B.最优肯定是全部都是1 C.直接统计每个余数下可以填多少个数&#xff0c;然后排序从小到大的排序输出即可 #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <queue> #inc…

Linux yum常用命令

Linux服务器安装成功后&#xff0c;我们会经常使用yum安装rpm包以满足使用的需要。使用yum源安装rpm包有两种方式&#xff1a; 方式一&#xff1a; 搭建本地yum源环境&#xff0c;进行rpm包的安装&#xff0c;具体搭建方式&#xff0c;参考(chapter-5)&#xff1a; Linux常规…

Android12之如何查看hidl服务(一百五十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

关闭网络钓鱼攻击 - 类型、方法、检测、预防清单

在当今互联互通的世界中&#xff0c;数字通信和交易占主导地位&#xff0c;网络钓鱼攻击已成为一种无处不在的威胁。 通过伪装成可信赖的实体&#xff0c;网络钓鱼攻击欺骗用户和组织泄露敏感信息&#xff0c;例如密码、财务数据和个人详细信息。 网络钓鱼攻击是网络罪犯使用…

【SpringCloud入门】-- 认识SpringCloudAlibabaNacos服务注册和配置中心

目录 1.Nacos是什么&#xff1f; 2.Nacos能干什么&#xff1f; 3. 各种服务注册中心比较 4.Nacos安装与运行 5.介绍一下Nacos图形化界面 6.NameSpace&#xff0c;Group&#xff0c;Data ID三者的关系&#xff1f;为什么这样设计&#xff1f; 7.Nacos集群和持久化配置 前…

MATLAB与自动化控制:控制系统设计、仿真和实现的应用和优化

章节一&#xff1a;介绍 自动化控制系统是现代工程中的关键组成部分&#xff0c;它在许多领域中发挥着重要作用&#xff0c;如机械工程、电气工程和航空航天工程等。在控制系统设计、仿真和实现过程中&#xff0c;MATLAB成为了一种强大的工具。本文将探讨MATLAB在自动化控制中…

用户模块封装数据模型层

数据模型层 数据模型层&#xff08;Data Model Layer&#xff09;是指在应用程序中用于表示和处理数据的模型层。这一层通常是应用程序的核心&#xff0c;因为它 负责从各种数据源获取数据并保证这些数据与应用程序的功能相匹配 。 在一个应用程序中&#xff0c;数据模型层通…

MidJourney使用教程:二 初识Prompts

最近AIGC这么火&#xff0c;除了chatGPT以外&#xff0c;这种图像类的产品也是非常有意思&#xff0c;其中就有MidJourney和Stable Diffusion这俩个比较出圈。这里我先选择MidJourney来体验并整理出一个教程。一方面MidJourney最简单&#xff0c;能当路Discord&#xff0c;注册…

正则替换的方式删除特定的内容

以前&#xff0c;公司网络限制&#xff0c;无法通过用户名密码登录某些网站&#xff0c;但是可以通过浏览器打开网站&#xff0c;而这些网站有个问题&#xff0c;非登录用户&#xff0c;不能复制博客中的代码&#xff0c;这个就有些麻烦了。 好在&#xff0c;这些代码是可以通过…

6.vue3医疗在线问诊项目 - _极速问诊-订单选择页面 ==> 问诊级别(普通/三甲)、科室选择(一级科室、二级科室)、病情描述、选择患者

6.vue3医疗在线问诊项目 - _极速问诊-订单选择页面 > 问诊级别&#xff08;普通/三甲&#xff09;、科室选择&#xff08;一级科室、二级科室&#xff09;、病情描述、选择患者 极速问诊-选择问诊级别-路由{#consult-change-type} 完成选择三甲还是普通问诊页面&#xff0c…

【Hadoop】大数据开发环境配置

【Hadoop】大数据开发环境配置 文章目录 【Hadoop】大数据开发环境配置1 设置静态ip2 设置主机名3 关闭防火墙4 ssh免密码登录5 JDK配置6 hadoop安装并配置6.1 集群节点之间时间同步6.2 SSH免密码登录完善6.3 hadoop配置 1 设置静态ip 进入ifcfg-ens33文件 vi /etc/sysconfig/n…

JAVA图形界面GUI

目录 一、窗口、窗格、按钮、标签 设置一个窗口JFrame 设置一个窗格JPanel和按钮JButton 设置一个标签JLabel 标准写法 二、监听器ActionListener 用内部类实现 用匿名内部类实现 用LAMADA表达式实现 三、文本域、复选框、下拉列表 JTextField单行文本域 JCheckBox复选…

智能算法终极大比拼,以CEC2017测试函数为例,十种智能算法直接打包带走,不含任何套路

包含人工蜂群(ABC)、灰狼(GWO)、差分进化(DE)、粒子群(PSO)、麻雀优化(SSA)、蜣螂优化(DBO)、白鲸优化(BWO)、遗传算法(GA)、粒子群算法(PSO)&#xff0c;基于反向动态学习的差分进化算法&#xff0c;共十种算法&#xff0c;直接一文全部搞定&#xff01; 其中基于反向动态学习…

Dalamud 插件开发白皮书 P1 - Getting started

文章目录 从哪里开始 How do I get started?Dalamud 插件例子Dalamud 底层探究XIVLauncher 启动器 在哪里寻找帮助 Where do I ask for help?如何热重载插件 How do I hot-reload my plugin?如何调试插件&#xff0c;甚至游戏&#xff1f;如何在编码过程中使用 How do I use…

国内几款强大的语言模型

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

STC15WProteus仿真红绿灯直行左右转紧急模式STC15W4K32S4-0041

STC15WProteus仿真红绿灯直行左右转紧急模式STC15W4K32S4-0041 Proteus仿真小实验&#xff1a; STC15WProteus仿真红绿灯直行左右转紧急模式STC15W4K32S4-0041 功能&#xff1a; 硬件组成&#xff1a;STC15W4K32S4单片机 2位数码管5个LED灯&#xff08;红 黄 ←绿 ↑绿 →绿…

《网络基础之socket理解》

【一】socket是什么 从字面上的意思来理解&#xff0c;这玩意的中文含义叫插座&#xff0c;对你想的没错&#xff0c;就是你家用来插电器的插座&#xff0c;只不过你家的插座是用来导电的&#xff0c;而网络里面的socket是用来传导信息的。 【二】网络socket传送数据流程 我们…

基于阻尼绕组起动同步电动机matlab完整程序分享

主要包含输出转速,感应转矩,磁场变化,感应电压,感应电流等6个参数变化曲线图!! 完整程序如下: clc; clear; close all; warning off; addpath(genpath(pwd)); %電機參數設定 r_stat_in=15;%stator內圈半徑 r_stat_out=17;%stator外圈半徑 width_rot=2;%rotor細部寬度 leng…

【瑞萨RA_FSP】DAC —— 输出正弦波

文章目录 一、DAC简介二、DAC的结构框图1. 参考电压2. 触发源3. DAC数据寄存器4. 转换的过程5. 同步转换 三、生成正弦波数据表四、DAC程序设计1. 硬件设计2. 软件设计①文件结构②FSP配置③DAC初始化函数④设置DAC输出电压函数⑤DAC输出正弦波⑥ hal_entry入口函数 一、DAC简介…

多用户商城软件有哪些开发方式?-加速度jsudo

电商时代之下&#xff0c;企业商家纷纷开始了b2b2c商城系统的搭建&#xff0c;以此来抢占电商市场&#xff0c;但由于大多企业商家并没有专业化的开发团队&#xff0c;所以大多会选择将网站建设外包给专业的商城系统开发公司&#xff0c;但就目前而言&#xff0c;b2b2c商城系统…