题意:
$2^k$个人玩石头剪刀布,他们站成一排,按照序号两两比赛,胜者进入下一轮,最后决出一个冠军
所有人在所有比赛中都会固定出石头剪刀布的一个,而且,他们每个人出哪一个的偏好如果按照序号排成序列,是一个循环的序列,而且循环节很有限,不会超过m
题解:
看到这个代码我是懵逼的
#include <bits/stdc++.h> #define rep(X, Y) for (int(X) = 0; (X) < (int)(Y); ++(X)) using namespace std; int main() { char win[222][222]; win['R']['R'] = win['R']['S'] = win['S']['R'] = 'R'; win['S']['S'] = win['S']['P'] = win['P']['S'] = 'S'; win['P']['P'] = win['P']['R'] = win['R']['P'] = 'P'; int n, m; string s; cin >> n >> m >> s; while (m--) { const auto t = s + s; rep(i, n) s[i] = win[t[i * 2]][t[i * 2 + 1]]; } cout << s[0] << endl; return 0; }
大意就是,按照比赛次序一层一层处理,处理出下一次比赛中,站在不同位置选手的出石头剪刀布的情况,由于每个人出什么是循环的,所以每行只需要考虑序号最前的,等同于循环节两倍的选手,得到在下一层中,一个新的循环节
再想想,实际上树的每一层都是以等长的循环节循环的,不妨假设这棵树高度无限,叶子节点数目也无限,我们要求的实际上是一棵子树的根节点