题目跳转

思路:这道题可能跟博弈论有一点关系,没有学习过博弈论做起来应该问题也不大。思考一个问题,先手必胜的前提是什么?

有关更多的内容可以前往:浅谈有向无环图

  • 先手必胜的前提是,在任何一种局面下,先手都有至少一种操作可以使后手处于必败的局面。
  • 若先手进行任何操作后,后手都可以选择必胜的操作,则先手无法必胜。
  • 如果当前玩家无法进行任何操作,那么对手获胜。

整体的思路就是通过递归不断搜索每一种决策情况,判断是否存在必胜的策略。

具体的实现方法:

创建两个函数,名为firstsecond

  1. first(x, y)函数返回当两位玩家分别选择数字xy时,先手是否必胜。
  2. second(x, y)函数返回当两位玩家分别选择数字xy时,后手是否必胜。

两个函数来回交替调用对方,即在first(x, y)函数中调用second(x, y)函数,在second(x, y)中调用first(x, y)。如果存在必胜的策略,返回true,否则返回false。若先手玩家无法再进行操作时,也返回false。

时间复杂度分析:本道题目将通过深度优先搜索DFS的方式来实现,每一层递归模拟某一位玩家的两个决策(将数字乘二或将数字除以三)。因此本道题目的时间复杂度大致为\(O(2^d)\),其中\(d\)表示递归的深度。考虑题目数据范围\(1 <= x, y <= 1000\),递归深度约为\(\log2(\frac{x+y}{2})\),完全可以在限定时间内通过所有的测试点。

参考代码一:

#include <iostream>
#include <cstring>
using namespace std; int vis[1005];
bool last(int x, int y); bool first(int x, int y){
bool isEnd, p1, p2;
isEnd = p1 = p2 = true;
if (x * 2 <= 1000 && !vis[x * 2]){
isEnd = false;
vis[x * 2] = 1;
p1 = last(x*2, y);
vis[x * 2] = 0;
}
if (x % 3 == 0 && !vis[x / 3]){
isEnd = false;
vis[x / 3] = 1;
p2 = last(x / 3, y);
vis[x / 3] = 0;
}
if (isEnd) return false;
// 如果后手有一条方案会必死,那么先手就一定赢。
return !(p1 && p2);
} bool last(int x, int y){
bool isEnd, p1, p2;
isEnd = p1 = p2 = true;
if (y * 2 <= 1000 && !vis[y * 2]){
isEnd = false;
vis[y * 2] = 1;
p1 = first(x, y * 2);
vis[y * 2] = 0;
}
if (y % 3 == 0 && !vis[y / 3]){
isEnd = false;
vis[y / 3] = 1;
p2 = first(x, y / 3);
vis[y / 3] = 0;
}
if (isEnd) return false;
return !(p1 && p2);
} int main(){
int t, x, y;
cin >> t;
while(t--){
memset(vis, 0, sizeof vis);
cin >> x >> y;
if (first(x, y)) cout << "Macw07" << endl;
else cout << "Penelope_77" << endl;
}
return 0;
}

参考代码二:

  1. decision(r)函数返回当两位玩家分别选择数字val[0]val[1]时,r选手(先手为0,后手为1)是否必胜。
#include <iostream>
#include <cstring>
using namespace std; int vis[1005];
int val[5]; bool decision(int r){
bool isEnd, p1, p2;
isEnd = p1 = p2 = true;
if (val[r] * 2 <= 1000 && !vis[val[r] * 2]){
isEnd = false;
val[r] *= 2;
vis[val[r]] = 1;
p1 = decision(!r);
vis[val[r]] = 0;
val[r] /= 2;
}
if (val[r] % 3 == 0 && !vis[val[r] / 3]){
isEnd = false;
val[r] /= 3;
vis[val[r]] = 1;
p2 = decision(!r);
vis[val[r]] = 0;
val[r] *= 3;
}
if (isEnd) return false;
return !(p1 && p2);
} int main(){
int t, x, y;
cin >> t;
while(t--){
memset(vis, 0, sizeof vis);
cin >> x >> y;
val[0] = x;
val[1] = y;
if (decision(0)) cout << "Macw07" << endl;
else cout << "Penelope_77" << endl;
}
return 0;
}

【题解】A18536.星光交错的律动的更多相关文章

  1. Codeforces Round #102 (Div. 2) 题解

    A. 解一个方程. 还是厚颜无耻地暴力吧~ #include <iostream> using namespace std; int r1, r2, c1, c2, d1, d2; boo ...

  2. 【cogs 597】【dp】交错匹配

    597. 交错匹配 ★☆ 输入文件:crossa.in 输出文件:crossa.out 简单对照 时间限制:1 s 内存限制:128 MB [问题描写叙述] 有两行自然数. UP[1..N] . DO ...

  3. 题解 P4093 【[HEOI2016/TJOI2016]序列】

    这道题原来很水的? noteskey 一开始以为是顺序的 m 个修改,然后选出一段最长子序列使得每次修改后都满足不降 这 TM 根本不可做啊! 于是就去看题解了,然后看到转移要满足的条件的我发出了黑人 ...

  4. JLOI2015 DAY2 简要题解

    「JLOI2015」骗我呢 题意 问有多少个 \(n \times m\) 的矩阵 \(\{x_{i, j}\}\) 满足 对于 \(\forall i \in [1, n], j \in [1, m ...

  5. 算法(第四版)C# 习题题解——1.1

    写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 善用 Ctrl + F 查找题 ...

  6. CQOI2018简要题解

    CQOI2018简要题解 D1T1 破解 D-H 协议 题意 Diffie-Hellman 密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码)的情况下,通过不安全的信 ...

  7. 【codeforces】【比赛题解】#862 CF Round #435 (Div.2)

    这次比赛打得很舒服,莫名得了个Rank41,涨了219的Rating,就比较优秀.不过还是没有闫神厉害啊.题目链接::P. [A]MEX 题意: Evil博士把Mahmoud和Ehab绑架到了邪恶之地 ...

  8. 【jsoi】第一季 [略]精简题解

    UPD:好像有两道题的代码逃跑了?= =就先不找了,反正都是水题. 精简题解系列第四弹.(其实也不是那么精简啊= =) [JSOI2008]最大数maxnumber 单点修改,区间最大值查询,裸线段树 ...

  9. Noip2016题解&总结

    原文放在我的uoj博客上,既然新开了blog,那就移过来了 玩具谜题(toy) 送分题.没有什么好说的. 直接按照题目的要求模拟即可. 标准的noip式day1T1. #include<cstd ...

  10. Bzoj 1997 [Hnoi2010]Planar题解

    1997: [Hnoi2010]Planar Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2224  Solved: 824[Submit][Stat ...

随机推荐

  1. 构筑立体世界,AR Engine助力B站会员购打造沉浸式营销

    随着购物场景的逐渐多元化,越来越多电商平台把线下购物体验搬到线上,运用AR技术,跨越空间距离,帮助用户在购买前"体验"商品,增强购买意愿. 哔哩哔哩会员购(后称会员购)是B站于20 ...

  2. QImage:使用QImage构造函数加载图像和使用成员函数loadFromData加载图像的区别

    结论: QImage构造函数,既可以加载内存图像数据,也可以加载二进制文件数据 loadFromData成员函数,只能加载二进制文件数据 loadFromData Qt帮助文档说明 编写测试代码验证 ...

  3. js实现电子白板

    功能:使用画笔绘制笔迹(线条).橡皮檫 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  4. 选择排序的基本实现【数据结构与算法—TypeScript 实现】

    笔记整理自 coderwhy 『TypeScript 高阶数据结构与算法』课程 概念 本质:两两元素相比较,先扫描一遍未排序数列,把未排序的数列中的最小(大)元素,放到数列的已排序的末尾 特性 选择排 ...

  5. HarmonyOS课程体验官招募(第四期),寻找乐于分享,精益求精的伙伴

      华为开发者联盟HarmonyOS课程体验官(第四期)活动,开始招募啦! 如果你精益求精.乐于分享:如果你愿意为学堂课程优化改进出谋划策,那就快来加入我们吧!学堂期待与你共同成长.一起进步! [活动 ...

  6. Vue保持用户登录状态(各种token存储方式)

    目录 怎么设置Cookie Cookie的缺点: LocalStorage与SessionStorage存储Token LocalStorage与SessionStorage的主要区别: Vuex存储 ...

  7. CentOS GNOME桌面下安装截图工具gnome-screenshot

    CentOS GNOME桌面下安装截图工具gnome-screenshot 1.光盘安装 (1).把镜像光盘放进电脑 (2).切换到 Packages (3).[root@localhost Pack ...

  8. Pytorch-实战之对Himmelblau函数的优化

    1.Himmelblau函数 Himmelblau函数: F(x,y)=(x²+y-11)²+(x+y²-7)²:具体优化的是,寻找一个最合适的坐标(x,y)使得F(x,y)的值最小. 函数的具体图像 ...

  9. Vue 路由组件传参的 8 种方式

    我们在开发单页面应用时,有时需要进入某个路由后基于参数从服务器获取数据,那么我们首先要获取路由传递过来的参数,从而完成服务器请求,所以,我们需要了解路由传参的几种方式,以下方式同 vue-router ...

  10. 【笔记】Oracle 窗口函数

    Oracle 窗口函数 简单来说,窗口函数是分析函数的一种,通常可以理解成over()函数 构成:函数名①() over(partition by 分组的列名 order by 排序的列名 XXX) ...