zoukankan      html  css  js  c++  java
  • UVALive 3668 A Funny Stone Game(博弈)

    Description 

    The funny stone game is coming. There are n piles of stones, numbered with 0, 1, 2,..., n - 1. Two persons pick stones in turn. In every turn, each person selects three piles of stones numbered ijk (i < jj$ leq$k and at least one stone left in pile i). Then, the person gets one stone out of pile i, and put one stone into pile j and pile k respectively. (Note: if j = k, it will be the same as putting two stones into pile j). One will fail if he can't pick stones according to the rule.

    David is the player who first picks stones and he hopes to win the game. Can you write a program to help him?

    The number of piles, n, does not exceed 23. The number of stones in each pile does not exceed 1000. Suppose the opponent player is very smart and he will follow the optimized strategy to pick stones.

    Input

    Input contains several cases. Each case has two lines. The first line contains a positive integer n ( $ leq$n$ leq$ 23) indicating the number of piles of stones. The second line contains n non-negative integers separated by blanks, S0,...Sn-1 ( $ leq$Si$ leq$ 1000), indicating the number of stones in pile 0 to pile n - 1respectively.

    The last case is followed by a line containing a zero.

    Output

    For each case, output a line in the format `` Game tijk". t is the case number. ij and k indicates which three piles David shall select at the first step if he wants to win. If there are multiple groups of ij and k, output the group with the minimized lexicographic order. If there are no strategies to win the game, ijand k are equal to -1.
     
    题目大意:有n堆石头,第i堆石头有Si个石头,每次可以从第i堆石头拿掉一个石头,然后在第j、k(i<j、k)上各放一个石头。两人轮流操作,不能操作的人算输,问先手第一步的必胜策略是什么,输出最小字典序的答案。
    思路:利用SG函数来做。可以把每个石头看作是独立的游戏,那么对于某个在第i位的石头,它的后续状态是所有的在第j、k位的两个石头,这两个石头也是独立的游戏,那么sg[i] = mex{sg[j] ^ sg[k]},对于每个位置的sg[i]可以O(n^3)预先计算出来。
    然后所有的石头的SG值异或若等于0则输出-1-1-1(对于每一个Si,若Si为奇数,则异或一次,若Si为偶数,则不异或,因为一个数异或偶数次,肯定是0,复杂度为O(n)),否则O(n^3)暴力枚举方案,若sg[i]^sg[j]^sg[k]^ans==0,则i、j、k是必胜方案,其中ans是所有石头SG值异或的结果。
    就是一步操作i、j、k,sg[i]会变成sg[j]^sg[k],那么若原来的SG值为ans,又sg[i]^sg[j]^sg[k]^ans==0,那么新状态的SG值就为0(可以参考NIM博弈的证明)。
     
    代码(3MS):
     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 const int MAXN = 23;
     8 
     9 int sg[MAXN + 5];
    10 bool mex[MAXN * MAXN];
    11 int n, s[MAXN];
    12 
    13 void build_sg() {
    14     for(int i = MAXN - 1; i >= 0; --i) {
    15         memset(mex, 0, sizeof(mex));
    16         for(int j = i + 1; j < MAXN; ++j) {
    17             for(int k = j; k < MAXN; ++k) mex[sg[j] ^ sg[k]] = true;
    18         }
    19         for(int j = 0; ; ++j)
    20             if(!mex[j]) {sg[i] = j; break;}
    21     }
    22 }
    23 
    24 void solve() {
    25     int ans = 0, *sg = ::sg + MAXN - n;
    26     for(int i = 0; i < n; ++i) ans ^= sg[i] * (s[i] & 1);
    27     if(ans == 0) {
    28         printf(" -1 -1 -1
    ");
    29         return ;
    30     }
    31     for(int i = 0; i < n; ++i) {
    32         if(s[i] == 0) continue;
    33         for(int j = i + 1; j < n; ++j) {
    34             for(int k = j; k < n; ++k) {
    35                 if((sg[i] ^ sg[j] ^ sg[k] ^ ans) == 0) {
    36                     printf(" %d %d %d
    ", i, j, k);
    37                     return ;
    38                 }
    39             }
    40         }
    41     }
    42 }
    43 
    44 int main() {
    45     build_sg();
    46     int cnt = 0;
    47     while(scanf("%d", &n) != EOF && n) {
    48         for(int i = 0; i < n; ++i) scanf("%d", &s[i]);
    49         printf("Game %d:", ++cnt);
    50         solve();
    51     }
    52 }
    View Code
  • 相关阅读:
    go语言中通过http访问需要认证的api
    Mysql两个time类型计算时间相减
    gorm中数据库datetime类型的映射和time.Time的格式化
    最详细的六种装饰器写法,学不会你找我!
    深度学习中的四种激活函数
    看完这篇文章,相信我,你已经掌握正则表达式了!
    新手还在问学Python应该看什么书,老手已经进来下载了(附100本pdf电子书下载)
    Python轻松实现一个毕业生信息管理系统!
    Python一键搞定批量合成PDF
    网易云10万+音乐竟然能用Python一键下载!
  • 原文地址:https://www.cnblogs.com/oyking/p/3533483.html
Copyright © 2011-2022 走看看