当前位置: 首页 > news >正文

网站建设规划案例seo文章外包

网站建设规划案例,seo文章外包,广州建设局,微网站建站系统源码问题描述 原题传送门:1.五子棋对弈 - 蓝桥云课 "在五子棋的对弈中,友谊的小船说翻就翻?" 不!对小蓝和小桥来说,五子棋不仅是棋盘上的较量,更是心与心之间的沟通。这两位挚友秉承着"友谊第…

问题描述

原题传送门:1.五子棋对弈 - 蓝桥云课

"在五子棋的对弈中,友谊的小船说翻就翻?" 不!对小蓝和小桥来说,五子棋不仅是棋盘上的较量,更是心与心之间的沟通。这两位挚友秉承着"友谊第一,比赛第二"的宗旨,决定在一块 5×5 的棋盘上,用黑白两色的棋子来决出胜负。但他们又都不忍心让对方失落,于是决定用一场和棋(平局)作为彼此友谊的见证。

比赛遵循以下规则:

棋盘规模:比赛在一个 5×5 的方格棋盘上进行,共有 25 个格子供下棋使用

棋子类型:两种棋子,黑棋与白棋,代表双方。小蓝持白棋,小桥持黑棋

先手规则:白棋(小蓝)具有先手优势,即在棋盘空白时率先落子(下棋)

轮流落子:玩家们交替在棋盘上放置各自的棋子,每次仅放置一枚

胜利条件:率先在横线、竖线或斜线上形成连续的五个同色棋子的一方获胜

平局条件:当所有 25 个棋盘格都被下满棋子,而未决出胜负时,游戏以平局告终

在这一设定下,小蓝和小桥想知道,有多少种不同的棋局情况,既确保棋盘下满又保证比赛结果为平局。

答案提交

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

问题分析

说实话在赛场看到这样的题目,说不慌张都是骗人的,尤其是其还放在填空题中,这对于我们这种水平偏中下的同学来说更是一个较为严峻的挑战。

本题在官方的难度分类中为中等题,但是在小玉看来,其难度就算在中等,那也是中等中偏难的那种,所以没有解题成功的同学并不需要慌张,也不要气馁,你能够在编程软件上敲下你的想法,就已经超过了赛场上的很多人!(这是真的!很多时候我们更应该做的是相信自己 (ง๑ •̀_•́)ง )

言归正传,万事开头难,我们先来简单分析一下这个题目!

这里的关键是统计所有可能的满盘棋局,并确保没有出现五子连珠的情况。由于棋盘规模是 5×5,共有 25!  种不同的落子顺序,直接遍历是不可行的,需要更高效的方法。

我们可以采用回溯 + 剪枝的方法进行搜索:

  1. 回溯搜索:逐步填充棋盘,每次轮流落子(白棋先手)。
  2. 剪枝:在填充的过程中,如果某个状态下已经形成五子连珠,则立即剪枝,不再继续。
  3. 终止条件:当棋盘填满时,若没有五子连珠的情况,则计数。

这个方法考虑了所有可能的棋局排列,并检查是否有五子连珠的情况。但由于 25!  过于庞大,直接使用排列组合的方法会导致计算量过大,优化点在于:

  • 使用位运算或更紧凑的数据结构 以减少存储开销
  • 提前剪枝 在确定某个局面已经形成五子连珠时尽早结束

如果需要进一步优化,可以考虑更复杂的数据结构如Zobrist哈希来避免重复计算。

上面是我一开始看到这个题目时脑子里所有冒出来的想法,先不管对不对,有想法就要坚持去实践!万一实现了呢 [狗头先欠着

下面是我开始解题时编写的python代码:

当然这个代码是错误的,因为只考虑到了逻辑上的可行性,并没有考虑到实际运算的可行性,有兴趣的同学可以将我错误示例与自己的相对比,在错误中学习

def generate_permutations(elements):"""递归生成列表元素的全排列(手工实现 permutations 生成器)参数:elements: list,需要生成排列的元素列表Yields:list: 一个排列组合"""# 基本情况:空列表只有一种排列(空列表)if len(elements) == 0:yield []else:# 遍历每个元素作为排列的第一个元素for i in range(len(elements)):# 排除当前元素后的剩余元素列表rest = elements[:i] + elements[i+1:]# 递归生成剩余元素的所有排列for p in generate_permutations(rest):# 将当前元素与子排列组合yield [elements[i]] + pdef check_five_in_a_row(board):"""检查五子棋棋盘是否存在五连珠情况参数:board: list[list[int]],5x5的二维数组,0表示空,1/2表示玩家返回:bool: 是否存在五连珠"""def check_line(x, y, dx, dy):"""检查从(x,y)出发,沿(dx,dy)方向是否存在五连珠参数:x, y: 起始坐标dx, dy: 方向步长(取值应为0或±1)返回:bool: 是否五连"""color = board[x][y]# 空位置直接返回否if color == 0:return False# 检查连续五个位置for i in range(1, 5):  # 只需要检查后续四个位置(共五个)nx, ny = x + i*dx, y + i*dy# 确保不会越界(根据调用方式其实不需要,但保留更安全)if nx >= 5 or ny >= 5 or nx < 0 or ny < 0:return Falseif board[nx][ny] != color:return Falsereturn True# 检查所有可能的五连珠路线for i in range(5):# 横向检查(每行的起始位置)if check_line(i, 0, 0, 1):return True# 纵向检查(每列的起始位置)if check_line(0, i, 1, 0):return True# 对角线检查return check_line(0, 0, 1, 1) or check_line(0, 4, 1, -1)def count_draw_games():"""计算所有可能的平局棋局数量(无五连珠的完整棋盘)注意:此实现因时间复杂度为O(25!)而无法实际运行,仅作为逻辑演示返回:int: 平局数量(理论值)"""# 生成所有棋盘位置坐标positions = [(i, j) for i in range(5) for j in range(5)]draw_count = 0# 遍历所有可能的落子顺序排列for perm in generate_permutations(positions):# 初始化空棋盘board = [[0] * 5 for _ in range(5)]# 模拟落子过程for turn, (x, y) in enumerate(perm):# 交替玩家落子(玩家1先手)board[x][y] = 1 if turn % 2 == 0 else 2# 每次落子后立即检查五连珠if check_five_in_a_row(board):break  # 出现五连则终止当前棋局else:# 完整25步且无五连珠的情况计数draw_count += 1return draw_count# 注意:实际运行时本代码无法完成计算
print(count_draw_games())

好!现在我们来真正地说一说本题的正确打开方式:

首先,如果你想要顺利的解出本题,那么你需要了解一个至关重要的知识点:将线性位置转换为二维坐标,这个思路可以用于解决所有和本题相似的题目中

如果你不清楚这个知识点,请你将下面得到两个式子记住,如果你想了解这个式子是如何推导得到的,欢迎访问我的个人网站,在算法必备知识点模块数学篇可以找到相关的推导(好吧现在网站没有了wuwuwuwu),好消息是,我找到了一个大佬写的解析:希望可以为你解惑关于坐标压缩式子的解压缩式子-CSDN博客

    x = (position - 1) // line_size + 1  # 行坐标y = (position - 1) % line_size + 1    # 列坐标

假设现在有一个坐标轴,那么其中的position为坐标轴上的刻度,也就是线性坐标X,line_size为你希望将其转换到二维坐标系下的坐标系长度(二维平面XOY,我们假设这个平面就像棋盘一样,每一边都有其边长,其中line_size就是这个边长),此后我们便可以通过这个式子计算转换之后的每个点对应的二维坐标!在本题中,我们还应该注意到:两条对角线索引计算的差异

  • 主对角线:x+y(范围2-10)

  • 副对角线:x-y+5(转换负数为正数,范围1-9)

其次,我们需要使用四个数组分别跟踪行、列、对角线的棋子差值(白棋+1,黑棋-1),由于棋盘上总共能放下 5x5 共25个棋子,且 白棋先手,轮流落子因此我们可以认为:

        初始白子:13颗

        初始黑子:12颗

而防止有一方连成5子赢得比赛,我们应该有对于二者棋子数量的    绝对值的限制(<4),以确保同一颜色不会出现5连。

这点也可以成为我们后续简化代码的关键剪枝条件:

  • 白棋条件:各方向统计值 <4(保证还能放白棋)

  • 黑棋条件:各方向统计值 >-4(保证还能放黑棋)

代码描述:

当分析到这里,对于知识点掌握比较扎实的同学应该可以猜到小玉要使用什么算法来解决本题了,没错!就是你想的那种!就是——记忆化搜索+启发式剪枝+并行计算(劝退)

我们大概来介绍一下这几个小方向:

  1. 记忆化搜索

     缓存重复出现的棋盘状态
  2. 并行计算

    将搜索树分解为多个子树并行处理
  3. 启发式剪枝

    提前识别无效路径(如双方都无法形成连线)

其实这三个内容在上面的思路分析部分已经多多少少提到过了,有没有课代表愿意画画重点呢?(要考的!)那么本题的具体代码如下,让我们跟着思路一步一步实现:

  1. 初始化棋盘尺寸和平局计数器

    • board_size 设置棋盘的大小为5。
    • draw_count 用来记录平局的次数。
       
      board_size = 5 # 棋盘边长,本题为正方形棋盘
      draw_count = 0 # 记录平局的次数

  2. 创建棋盘状态跟踪系统

    • 使用四个数组来分别跟踪行、列、主对角线和副对角线上的棋子差值。白棋记为+1,黑棋记为-1。

    • row_count:行差值统计数组,长度为 board_size + 1,索引从1开始。

    • col_count:列差值统计数组,长度和索引同上。

    • main_diag_count:主对角线差值统计数组,长度为 2 * board_size + 1,索引对应于对角线上的位置。

    • anti_diag_count:副对角线差值统计数组,长度同上,索引对应于副对角线上的位置。

      # 统计数组,分别记录行、列、主对角线、副对角线的棋子数
      row_count = [0] * (board_size + 1)
      col_count = [0] * (board_size + 1)
      main_diag_count = [0] * (2 * board_size + 1)
      anti_diag_count = [0] * (2 * board_size + 1)
  3. 定义递归函数 count_draw_games

    • 参数 position 表示当前放置棋子的位置(从1开始)。

    • 参数 white_pieces 和 black_pieces 分别表示剩余可以放置的白棋和黑棋的数量。

    • 从线性坐标轴上看,当 position 达到棋盘大小的平方加一时,表示所有位置已填满,此时增加 draw_count,即达到和棋条件

    • 将线性位置转换为二维坐标(行 x 和列 y)。

  4. def count_draw_games(position, white_pieces, black_pieces):global draw_count# 终止条件:所有位置已填满if position == board_size * board_size + 1:draw_count += 1return# 将线性位置转换为二维坐标(1-based)x = (position - 1) // board_size + 1  # 行坐标(1-5)y = (position - 1) % board_size + 1    # 列坐标(1-5)# 尝试放置白棋(先手方需要多一个棋子)if white_pieces > 0:# 剪枝条件:保证所有方向上白棋不超过4个if (row_count[x] < board_size - 1 and           # 行方向还能放白棋col_count[y] < board_size - 1 and           # 列方向还能放白棋main_diag_count[x + y] < board_size - 1 and # 主对角线方向anti_diag_count[x - y + board_size] < board_size - 1): # 副对角线方向# 更新所有跟踪数组row_count[x] += 1col_count[y] += 1main_diag_count[x + y] += 1anti_diag_count[x - y + board_size] += 1# 递归处理下一个位置count_draw_games(position + 1, white_pieces - 1, black_pieces)# 回溯:恢复状态row_count[x] -= 1col_count[y] -= 1main_diag_count[x + y] -= 1anti_diag_count[x - y + board_size] -= 1# 尝试放置黑棋if black_pieces > 0:# 剪枝条件:保证所有方向上黑棋不超过4个# 注意这里的比较方向是反的(因为黑棋用负数表示)if (row_count[x] > 1 - board_size and           # 行方向还能放黑棋col_count[y] > 1 - board_size and           # 列方向还能放黑棋main_diag_count[x + y] > 1 - board_size and # 主对角线方向anti_diag_count[x - y + board_size] > 1 - board_size):# 更新所有跟踪数组(黑棋用减法)row_count[x] -= 1col_count[y] -= 1main_diag_count[x + y] -= 1anti_diag_count[x - y + board_size] -= 1# 递归处理下一个位置count_draw_games(position + 1, white_pieces, black_pieces - 1)# 回溯:恢复状态row_count[x] += 1col_count[y] += 1main_diag_count[x + y] += 1anti_diag_count[x - y + board_size] += 1

    以上便是本题的所有代码了,以下是上述代码的总结:

    # 棋盘尺寸
    board_size = 5
    # 平局计数器
    draw_count = 0"""
    创新性的棋盘状态跟踪系统:
    使用四个数组分别跟踪行、列、对角线的棋子差值(白棋+1,黑棋-1)
    这种设计使得我们可以在 O(1) 时间内判断是否允许落子
    """
    # 行差值统计(索引1-5)
    row_count = [0] * (board_size + 1)
    # 列差值统计(索引1-5)
    col_count = [0] * (board_size + 1)
    # 主对角线(左上到右下)差值统计(x+y范围:2-10)
    main_diag_count = [0] * (2 * board_size + 1)
    # 副对角线(右上到左下)差值统计(x-y+5范围:1-9)
    anti_diag_count = [0] * (2 * board_size + 1)def count_draw_games(position, white_pieces, black_pieces):global draw_count# 终止条件:所有位置已填满if position == board_size * board_size + 1:draw_count += 1return# 将线性位置转换为二维坐标(1-based)x = (position - 1) // board_size + 1  # 行坐标(1-5)y = (position - 1) % board_size + 1    # 列坐标(1-5)# 尝试放置白棋(先手方需要多一个棋子)if white_pieces > 0:# 剪枝条件:保证所有方向上白棋不超过4个if (row_count[x] < board_size - 1 and           # 行方向还能放白棋col_count[y] < board_size - 1 and           # 列方向还能放白棋main_diag_count[x + y] < board_size - 1 and # 主对角线方向anti_diag_count[x - y + board_size] < board_size - 1): # 副对角线方向# 更新所有跟踪数组row_count[x] += 1col_count[y] += 1main_diag_count[x + y] += 1anti_diag_count[x - y + board_size] += 1# 递归处理下一个位置count_draw_games(position + 1, white_pieces - 1, black_pieces)# 回溯:恢复状态row_count[x] -= 1col_count[y] -= 1main_diag_count[x + y] -= 1anti_diag_count[x - y + board_size] -= 1# 尝试放置黑棋if black_pieces > 0:# 剪枝条件:保证所有方向上黑棋不超过4个# 注意这里的比较方向是反的(因为黑棋用负数表示)if (row_count[x] > 1 - board_size and           # 行方向还能放黑棋col_count[y] > 1 - board_size and           # 列方向还能放黑棋main_diag_count[x + y] > 1 - board_size and # 主对角线方向anti_diag_count[x - y + board_size] > 1 - board_size):# 更新所有跟踪数组(黑棋用减法)row_count[x] -= 1col_count[y] -= 1main_diag_count[x + y] -= 1anti_diag_count[x - y + board_size] -= 1# 递归处理下一个位置count_draw_games(position + 1, white_pieces, black_pieces - 1)# 回溯:恢复状态row_count[x] += 1col_count[y] += 1main_diag_count[x + y] += 1anti_diag_count[x - y + board_size] += 1# 初始化递归(白棋13个,黑棋12个)
    count_draw_games(1, (board_size * board_size + 1) // 2, board_size * board_size // 2)print(draw_count)

结果提交

上述代码的运行结果:

将上述代码提交到蓝桥杯官网

写在后面

本题的成功解决也告诉我们,不应该随便忽略题设中的任何一个条件和字眼,也就是:审题是务必全面仔细!!!实际赛场中,如果你在未完全使用题设条件的前提下编写出了代码,那其在实际测试时的样例通过率可能会非常感人😭😭😭

有小伙伴私信提到实际运行时间上的问题,我想说的是,实际赛场上的测试软件中,对于python这个编程语言还是比较宽容的,所以其实并不用太过于焦虑担心运行用时这块的问题。

且本题只是一个填空题,并不需要多高超的解题方法,在分析实际代码的时间复杂度允许的情况下,我们完全可以选择舍弃一点时间来换取答案的准确性。

那么对于上述代码,其实还可以在某些地方再次进行简化,亲爱的小伙伴,请问你看出来了吗?欢迎在评论区交流哦~


文章转载自:
http://deconvolution.c7498.cn
http://peri.c7498.cn
http://chained.c7498.cn
http://fortyish.c7498.cn
http://xanthochroism.c7498.cn
http://monolithic.c7498.cn
http://comfortable.c7498.cn
http://pluviose.c7498.cn
http://haziness.c7498.cn
http://counsellor.c7498.cn
http://carved.c7498.cn
http://mollescent.c7498.cn
http://guestchamber.c7498.cn
http://unembellished.c7498.cn
http://obligation.c7498.cn
http://vulvitis.c7498.cn
http://cigala.c7498.cn
http://cullender.c7498.cn
http://geneticist.c7498.cn
http://alternating.c7498.cn
http://monophthongize.c7498.cn
http://sinful.c7498.cn
http://limpa.c7498.cn
http://spoliate.c7498.cn
http://thyrotropic.c7498.cn
http://plateholder.c7498.cn
http://refuel.c7498.cn
http://diplopod.c7498.cn
http://blonde.c7498.cn
http://demerol.c7498.cn
http://ohmmeter.c7498.cn
http://estimator.c7498.cn
http://preplan.c7498.cn
http://diacritic.c7498.cn
http://lastness.c7498.cn
http://bootstrap.c7498.cn
http://iucd.c7498.cn
http://xerophile.c7498.cn
http://flechette.c7498.cn
http://unpublicized.c7498.cn
http://srna.c7498.cn
http://teamwork.c7498.cn
http://ghyll.c7498.cn
http://abridgment.c7498.cn
http://electrometallurgy.c7498.cn
http://gallery.c7498.cn
http://diana.c7498.cn
http://magnicide.c7498.cn
http://thoracostomy.c7498.cn
http://apophyllite.c7498.cn
http://ogrish.c7498.cn
http://monohull.c7498.cn
http://livetrap.c7498.cn
http://incorrectness.c7498.cn
http://aisne.c7498.cn
http://retgersite.c7498.cn
http://divaricator.c7498.cn
http://oxfordshire.c7498.cn
http://premed.c7498.cn
http://naevi.c7498.cn
http://souther.c7498.cn
http://goethean.c7498.cn
http://syncaine.c7498.cn
http://porkbutcher.c7498.cn
http://longhair.c7498.cn
http://arica.c7498.cn
http://savageness.c7498.cn
http://tripartisan.c7498.cn
http://epochmaking.c7498.cn
http://jab.c7498.cn
http://okro.c7498.cn
http://calisthenic.c7498.cn
http://gristmill.c7498.cn
http://trapezia.c7498.cn
http://ugric.c7498.cn
http://exaggeratory.c7498.cn
http://eightfold.c7498.cn
http://succubi.c7498.cn
http://sixthly.c7498.cn
http://shnook.c7498.cn
http://atlantis.c7498.cn
http://claqueur.c7498.cn
http://disadvantaged.c7498.cn
http://lanthanum.c7498.cn
http://seeper.c7498.cn
http://intercommunion.c7498.cn
http://stifle.c7498.cn
http://agrologic.c7498.cn
http://vivandiere.c7498.cn
http://yarrow.c7498.cn
http://anastigmat.c7498.cn
http://wushu.c7498.cn
http://porte.c7498.cn
http://cosey.c7498.cn
http://heteroatom.c7498.cn
http://stele.c7498.cn
http://heraldry.c7498.cn
http://metz.c7498.cn
http://chirpy.c7498.cn
http://recentness.c7498.cn
http://www.zhongyajixie.com/news/67920.html

相关文章:

  • 校园网站源码php抖音关键词排名软件
  • 游戏网站怎么做正规网络教育培训机构
  • 网站开发与设计教程广告联盟怎么加入
  • ubuntu做php网站网站seo设计
  • 网站检索功能怎么做呢百度seo 优化
  • 网站建设公司怎么盈seo网络优化专员是什么意思
  • 电影网站盗链怎么做360搜索引擎入口
  • 网站建设思维导图seo关键词
  • 网站备案信息查询西安做推广优化的公司
  • wordpress怎么加地图天津百度快速排名优化
  • 怎么做网站树洞全网推广平台
  • 网站的电子画册怎么做网站seo快速
  • 工业设计的就业前景成都优化官网公司
  • 专业的网站服务公司互联网营销师证书怎么考多少钱
  • 沈阳建设公司网站企业培训课程名称大全
  • 做网站需要源码网络推广渠道公司
  • 如何快速提升网站pr网站目录提交
  • wordpress主题官方网站百度网址入口
  • 夏门建设局网站百度企业官网
  • 网上免费做网站常州seo收费
  • 盐城专业做网站较好的公司哪个软件可以自动排名
  • 云南昆州建设工程有限公司网站缅甸新闻最新消息
  • 深圳网站建设小程序网站优化推广外包
  • 网站建设网站制作有限优化排名seo
  • 网站建设公司普遍存在劣势seo新站如何快速排名
  • 长沙招工 最新招聘信息关键词搜索优化外包
  • 北京做网站公司排最新国内新闻重大事件
  • 大连市场所码二维码图片成都排名seo公司
  • app与微网站的区别是什么今日最新重大新闻
  • ai智能ppt制作东莞seo托管