ARC109C Large RPS Tournament 机智

传送门

题意:

$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;
}

大意就是,按照比赛次序一层一层处理,处理出下一次比赛中,站在不同位置选手的出石头剪刀布的情况,由于每个人出什么是循环的,所以每行只需要考虑序号最前的,等同于循环节两倍的选手,得到在下一层中,一个新的循环节

再想想,实际上树的每一层都是以等长的循环节循环的,不妨假设这棵树高度无限,叶子节点数目也无限,我们要求的实际上是一棵子树的根节点

原文地址:https://www.cnblogs.com/isakovsky/p/14163073.html