HDU 3980 Paint Chain

题目链接:HDU 3980【Paint Chain】



思路

       第一次操作,无论从哪个珠子开始染色,都会得到相同的长度为n - m的链,然后就是在这条链中取一段长度为m的珠子染色,当这一段珠子在链条中间的时候,就会把链条分成两段,就是一个简单的两段连续珠子的长度的sg值异或一下,求出sg[n - m]的值之后,因为aekdycoin操作了一次才从长度为n的环得到现在的状态,所以先手操作的sg值为!sg[n - m]。同时还得特判m大于n的情况,m > n时,第一次操作都不能进行,先手必败。


代码

int n, m, vis[N], sg[N], test;

void SG() {
  memset(sg, 0, sizeof sg);
  memset(vis, 0, sizeof vis);
  for (int i = m; i <= n; i++) {
    for (int j = 0; j + m <= i; j++) {
      // 枚举从第j个珠子开始涂色
      vis[sg[j] ^ sg[i - j - m]] = i;
    }
    while (vis[sg[i]] == i) {
      sg[i]++;
    }
  }
}

void solve() {
  test++;
  n = read(), m = read();
  SG();
  cout << "Case #" << test << ": ";
  if (n >= m && sg[n - m] == 0) {
    // 因为无论从哪个珠子开始染色得到的都是长度为n - m的链,然后就是简单的分堆
    cout << "aekdycoin" << endl;
  } else {
    cout << "abcdxyzk" << endl;
  }
}

int main() {
  int t = read();
  while (t--)
    solve();
  return 0;
}
posted @ 2024-08-16 11:41  薛定谔的AC  阅读(4)  评论(0编辑  收藏  举报