IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 【蓝桥杯】【python】高僧斗法 -> 正文阅读

[Python知识库]【蓝桥杯】【python】高僧斗法

问题描述

思路(Nim博弈)

Nim博弈在这篇文章写的很好:

https://blog.csdn.net/qq_41923622/article/details/86707861

因为数学功底不扎实,所以我在这边只说结论:

以题目给出案例为例:

将两个和尚之间的距离分别拿出来生成一个新的列表

也即是:3 (由 5 - 1 - 1,得到);3 (由9 - 5 - 1 得到)

首先将其转换成二进制再异或比较得到结果

异或用符号^,例如2 ^ 3 = 1,即分别求出2和3的二进制,再进行比较,相同为0,不相同为1

如果结果是0,那就是后手必赢,如果结果非0,那先手必赢

所以此处先手必赢,那为了使后手输,就得把移动和尚来使得相加的结果为0

注:为什么进行异或计算时,每两个和尚组成一堆,所以每两个堆一个组:

在原文作者石头的例子中,直接就是按照石头堆的数量进行计算。而在我们题目中,首先计算间隔来等效替代各堆石头的数量,但是本题中移动一个的位置会影响两堆的数量,因此采用两堆组成一组的形式,所以在异或计算时也是采用步长为2.

总结就是改变一个,多少会随之而改变,就利用这个作为一组

代码

# main
# 输入数据,并将位置信息转换成间隔信息,也即是Nim转换
pos = input().split()
heap = [0 for _ in range(len(pos) - 1)]
for i in range(len(pos)):
    pos[i] = int(pos[i])
# Nim转换
for i in range(len(pos) - 1):
    heap[i] = pos[i + 1] - pos[i] - 1
# 进行异或计算
temp_sum = 0
for i in range(0, len(pos) - 1, 2):
    temp_sum ^= heap[i]
# 进行判断
if sum == 0:
    print(-1)
else:
    temp_j = 1000
    for i in range(len(pos) - 1):
        for j in range(1, temp_j):
            if(pos[i] +j >= pos[i + 1]):
                break
            else:
                heap[i] -= j
                if(i != 0):
                    heap[i - 1] += j
                    
                sum = 0
                for k in range(0, len(pos) - 1, 2):
                    sum ^= heap[k]
                    
                if(sum == 0):
                    print(pos[i], pos[i] + j)
                    heap[i] += j
                    if i != 0:
                        heap[i - 1] -= j
                    j += 1
                    continue
                else:
                    heap[i] += j
                    if i != 0:
                        heap[i - 1] -= j
                    j += 1

文字描述:

预处理得到min转换后的列表,和位置信息

判断过程:

如果异或得到0,那就返回-1

不然,以位置为循环,然后遍历往前走的步数

如果超过前面一位了,那就break,不然的话,将前后的heap和pos的列表信息进行更改,并且需要注意在i == 0的情况下,需要进行更改

然后在再计算其异或值,如果为0那就输出,如果不是,那就回溯,将值变换回原来的值。

疑问:

最初我看的是c语言网上一个同学的代码,然后我发现了一个问题(这是他的代码)

k=list(map(int,input().strip().split()))
kl=len(k)
b=[0 for _ in range(kl-1)]#堆的数量是和尚数-1
for i in range(1,kl): #放堆
    b[i-1]=k[i]-k[i-1]-1
sum=0
for i in range(0,kl-1,2):#进行异或,每两个和尚组成一堆,所以每两个堆一组,所以步数为2
    sum^=b[i]
if sum==0: #若开始局面为0 则必输
    print(-1)
else:#若非0 则必赢,因此 需要找到第一步 将局面变为0 的步骤
    for i in range(kl-1):#枚举移动第i堆  使得剩下的局面异或等于0,
        j=1
        while True:#枚举可以移动的步数  保证 前项移动j 步后 不会超过后项
            # print(k)
            if k[i]+j>=k[i+1]:
                break
            b[i] -= j #拿走 j个 ,这里代表 前一个向上移动j步
            if(i!=0):
                b[i-1] += j #它的后一堆b[i]向取走了j个,那莫前一堆 b[i-1] 则要增加j个 第一堆除外
            sum=0
            for s in range(0,kl-1,2):#进行异或,重新计算局面
                sum^=b[s]
            if sum==0:
                print(k[i],k[i]+j)#若变成0  则后手必败,先手必赢。跳出即可;
                break
            b[i] += j #回溯 这不是必赢的操作
            if i!=0:
                b[i-1] -= j
            j+=1

如果对于一个小和尚来说,不止一种移动方式,例如小和尚a往前走5步可以,往前走12步也可以达到要求,那这种回溯方法其实会省略后一种走法,所以我进行了更改,在break改成continue后重复一段回溯过程

然后应该是大于等于,不然可能导致两个小和尚站在一个台阶上的情况

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-02-04 10:59:51  更:2022-02-04 11:01:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:14:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码