2022-12-02:有a块草莓蛋糕,有b块芝士蛋糕,两人轮流拿蛋糕, 每次不管是谁只能选择在草莓蛋糕和芝士蛋糕中拿一种, 拿的数量在1~m之间随意, 谁先拿完最后的蛋糕谁赢。 返回先手赢还是后手赢。
2022-12-02:有a块草莓蛋糕,有b块芝士蛋糕,两人轮流拿蛋糕,
每次不管是谁只能选择在草莓蛋糕和芝士蛋糕中拿一种,
拿的数量在1~m之间随意,
谁先拿完最后的蛋糕谁赢。
返回先手赢还是后手赢。
nim博弈。
答案2022-12-02:
找规律法。
1.a==b
蛋糕一样多
先手必输,因为先手不管拿什么,拿多少
后手都在另一堆上,拿同样多的蛋糕
继续让两堆蛋糕一样多
最终先手必输,后手必赢
2.a!=b
如果 a != b
关注a和b的差值,
谁最先遇到差值为0,谁输
那么这就是巴什博奕
差值蛋糕数量共rest个。
每次从最少取1个,最多取m个,最后取光的人取胜。
如果rest=(m+1)*k + s (s!=0) 那么先手一定必胜
因为第一次取走s个,
接下来无论对手怎么取,
先手都能保证取到所有(m+1)倍数的点,
那么循环下去一定能取到差值最后一个。
时间复杂度:O(1)。
空间复杂度:O(1)。
代码用rust编写。代码如下:
use std::iter::repeat;
fn main() {
let vv = 100;
println!("测试开始");
for a in 0..=vv {
for b in 0..vv {
for m in 0..vv {
let ans1 = who_win1(a, b, m);
let ans2 = who_win2(a, b, m);
if ans1 != ans2 {
println!("出错了!");
println!("a : {}", a);
println!("b : {}", b);
println!("m : {}", m);
println!("ans1 : {}", ans1);
println!("ans2 : {}", ans2);
}
}
}
}
println!("测试结束");
}
// 草莓蛋糕a块
// 巧克力蛋糕b块
// 每次可以在任意一种上拿1~m块
// 返回谁会赢,"先手" or "后手"
static mut dp: [[[&str; 101]; 101]; 101] = [[[""; 101]; 101]; 101];
fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
}
fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}
// 暴力方法
// 为了验证
fn who_win1(a: i32, b: i32, m: i32) -> &'static str {
if m >= get_max(a, b) {
// nim博弈
return if a != b { "先手" } else { "后手" };
}
if a == b {
// 蛋糕一样多
// 先手必输,因为先手不管拿什么,拿多少
// 后手都在另一堆上,拿同样多的蛋糕
// 继续让两堆蛋糕一样多
// 最终先手必输,后手必赢
return "后手";
}
if unsafe { dp[a as usize][b as usize][m as usize] } != "" {
return unsafe { dp[a as usize][b as usize][m as usize] };
}
let mut ans = "后手";
for pick in 1..=get_min(a, m) {
if who_win1(a - pick, b, m) == "后手" {
ans = "先手";
}
if ans == "先手" {
break;
}
}
for pick in 1..=get_min(b, m) {
if who_win1(a, b - pick, m) == "后手" {
ans = "先手";
}
if ans == "先手" {
break;
}
}
unsafe {
dp[a as usize][b as usize][m as usize] = ans;
}
return ans;
}
// 正式解法
// 时间复杂度O(1)
// 先看nim博弈
fn who_win2(a: i32, b: i32, m: i32) -> &'static str {
// if m >= get_max(a, b) {
// // nim博弈
// return if a != b { "先手" } else { "后手" };
// }
// m < max(a,b)
if a == b {
// 蛋糕一样多
// 先手必输,因为先手不管拿什么,拿多少
// 后手都在另一堆上,拿同样多的蛋糕
// 继续让两堆蛋糕一样多
// 最终先手必输,后手必赢
return "后手";
}
// 如果 a != b
// 关注a和b的差值,
// 谁最先遇到差值为0,谁输
// 那么这就是巴什博奕
// 差值蛋糕数量共rest个。
// 每次从最少取1个,最多取m个,最后取光的人取胜。
// 如果rest=(m+1)*k + s (s!=0) 那么先手一定必胜
// 因为第一次取走s个,
// 接下来无论对手怎么取,
// 先手都能保证取到所有(m+1)倍数的点,
// 那么循环下去一定能取到差值最后一个。
let rest = get_max(a, b) - get_min(a, b);
return if rest % (m + 1) != 0 {
"先手"
} else {
"后手"
};
}
执行结果如下:

2022-12-02:有a块草莓蛋糕,有b块芝士蛋糕,两人轮流拿蛋糕, 每次不管是谁只能选择在草莓蛋糕和芝士蛋糕中拿一种, 拿的数量在1~m之间随意, 谁先拿完最后的蛋糕谁赢。 返回先手赢还是后手赢。的更多相关文章
- HP LoadRunner 12.02 Tutorial T7177-88037教程独家中文版
HP LoadRunner 12.02 Tutorial T7177-88037教程独家中文版 Tylan独家呕血翻译 转载请注明出自“天外归云”的博客园 Welcome to the LoadRun ...
- [原创]LoadRunner 12.02 录制脚本时提示无Internet访问,如何解决?
在使用LoadRunner 12.02 进行录制脚本时提示无Internet访问,如下图: 翻译中文如下: 可以尝试以下方式解决:点击弹出框中的“Yes”即可. 若还是有问题,尝试以下方式: (1)L ...
- [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装
[原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...
- LoadRunner 12.02 安装教程及中文语言包安装
注意事项: 安装前,把所有的杀毒软件和防火墙关闭. 若以前安装过LoadRunner,则将其卸载. 安装路径不要带中文字符. LoadRunner 12已经不再支持xp系统,仅支持win7和win8系 ...
- LoadRunner 12.02 安装以及汉化教程
LoadRunner 12.02 安装 一.下载 首先下载Loadrunner12安装包. 下载后有四个安装包: HP_LoadRunner_12.02_Community_Edition_Addit ...
- 2018.12.02 Socket编程之初识Socket
Socket编程主要分为TCP/UDP/SCTP三种,每一种都有各自的优点,所以会根据实际情况决定选用何种Socket,今天开始我将会逐步学习Socket编程,并将学习过程记录于此. 今天学习的是TC ...
- 2021.12.02 P4001 [ICPC-Beijing 2006]狼抓兔子(最小割)
2021.12.02 P4001 [ICPC-Beijing 2006]狼抓兔子(最小割) https://www.luogu.com.cn/problem/P4001 题意: 把图分成两部分需要的最 ...
- 12、Java并发性和多线程-Java同步块
以下内容转自http://ifeve.com/synchronized-blocks/: Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免 ...
- java类静态域、块,非静态域、块,构造函数的初始化顺序
原文:http://ini.iteye.com/blog/2007835 面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量, 构造器里可能还有 ...
- CSS 布局实例系列(四)如何实现容器中每一行的子容器数量随着浏览器宽度的变化而变化?
Hello,小朋友们,还记得我是谁吗?对了,我就是~超威~好啦,言归正传,今天的布局实例是: 实现一个浮动布局,红色容器中每一行的蓝色容器数量随着浏览器宽度的变化而变化,就如下图: 肯定有人心里犯嘀咕 ...
随机推荐
- 记录linux上无法和本地传输文件
在学习docker搭建nacos的过程中,涉及到上传本地文件,但是包括从xshell直接拖拽还是xftp上传,都是失败, 最后百度查找多种不同的结果,最后实验下来是文件夹没有权限的问题. 解决步骤如下 ...
- 【故障公告】cc攻击又来了,雪上加霜的三月
非常非常抱歉!今天 21:20-22:10 左右,肆无忌惮的 cc 攻击又来了,蓄意攻击者很厉害,躲过阿里云云盾的黑洞机制,轻松击垮园子的博客站点,又给大家带来了很大的麻烦,请大家谅解! 今年3月是园 ...
- Command Injection-命令注入(命令执行)
什么是命令注入? 命令注入是滥用应用程序的行为在操作系统上执行命令,使用与设备上的应用程序运行时相同的权限.例如,在作为名为joe的用户运行的web服务器上实现命令注入将在该joe用户下执行命令,从而 ...
- Xenomai 再探
一.Xenomai API 接口使用总结 Alarm-操作: 在使用实时任务过程中,采用看门狗定时器进行延时操作时,会产生实时域到非实时域的上下文切换操作,从而导致实时线程实时性受到影响,具体如下: ...
- C++ 猜数字
#include <iostream> #include <random> #include <limits> namespace random { std::ra ...
- vue在js公用文件中使用this
main.js 中 let $vue = new Vue({ router, el: '#app', render: h => h(App) }); export default $vue 在j ...
- ChatGPT 开源了第一款插件,都来学习一下源码吧!
3 月 23 日,OpenAI 又投出了一枚重磅炸弹:为 ChatGPT 推出插件系统! 此举意味着 ChatGPT 将迎来"APP Store"时刻,也就是围绕它的能力,形成一个 ...
- NEFUOJ P903字符串去星问题
Description 有一个字符串(长度小于100),要统计其中有多少个,并输出该字符串去掉后的新字符串. Input 输入数据有多组,每组1个连续的字符串; Output 在1行内输出该串内有多少 ...
- cs 保研经验贴 | 综合面试题库
绝大部分夏令营都需要面试:如果幸运的话,稍微问几个问题就结束了:不幸的话,可能要抓住你做项目.读论文.复现.做 pre 等等. 这篇博客适用于幸运的情况:绝大部分学校的面试题库,都是彼此重合的,并且一 ...
- 6步带你用Spring Boot开发出商城高并发秒杀系统
摘要:本博客将介绍如何使用 Spring Boot 实现一个简单的商城秒杀系统,并通过使用 Redis 和 MySQL 来增强其性能和可靠性. 本文分享自华为云社区<Spring Boot实现商 ...