zoukankan      html  css  js  c++  java
  • LightOJ 1229 Treblecross(SG函数打表 + 遍历)题解

    题意:给你一串含“.”和“X”的字串,每次一个玩家可以把‘."变成“X”,谁先弄到三个XXX就赢。假如先手必赢,输出所有能必赢的第一步,否则输出0。

    思路:显然如果一个X周围两格有X那么肯定能一步变成XXX,所以两个人都要避免在自己回合产生这种情况。如果一开始就存在上述情况,那么肯定是那一步。否则我遍历每一个空格看看能不能下这一步。满足我在这个空格变成“X”不会造成上述情况,然后算出nim和是否留给对手一个必败态。

    设sg[x]表示长度为x的空格的sg函数,然后我遍历1~x位置变成“X”,那么空格键会被我分成两块(比如.....我在3位置下X,那么空格被我分成了左0右0两块,注意X旁边两块不能动)。

    代码:

    #include<set>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    const int maxn = 200 + 10;
    const int seed = 131;
    const ll MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    int sg[maxn], s[maxn], ans[maxn], pos;
    char str[maxn];
    void getSG(){
        sg[0] = 0;
        for(int i = 1; i < maxn; i++){
            memset(s, 0, sizeof(s));
            for(int j = 1; j <= i; j++){
                int t = 0;
                if(i - j - 2 >= 0) t ^= sg[i - j - 2];
                if(j - 3 >= 0) t ^= sg[j - 3];
                s[t] = 1;
            }
            for(int j = 0; j < maxn; j++){
                if(!s[j]){
                    sg[i] = j;
                    break;
                }
            }
        }
    }
    bool check(){
        ll ret = 0;
        int num = 0, len = strlen(str);
        for(int i = 0; i < len; i++){
            if(str[i] == 'X'){
                if((i >= 1 && str[i - 1] == 'X') || (i >= 2 && str[i - 2] == 'X') || (i + 1 < len && str[i + 1] == 'X') || (i + 2 < len && str[i + 2] == 'X')){
                    return false;
                }
                if(str[i - num - 1] == 'X' && i - num - 1 >= 0)
                    num -= 2;
                num -= 2;
                if(num >= 0) ret ^= sg[num];
                num = 0;
            }
            else{
                num++;
            }
        }
        if(str[len - 1 - num] == 'X' && len - 1 - num >= 0)
                num -= 2;
        if(num >= 0) ret ^= sg[num];
        return ret == 0;
    }
    void solve(){
        pos = 0;
        int len = strlen(str);
        for(int i = 0; i < len; i++){
            if(str[i] == '.'){
                str[i] = 'X';
                if(i + 1 < len && i - 1 >= 0 && str[i + 1] == 'X' && str[i - 1] == 'X'){
                    ans[pos++] = i + 1;
                }
                else if(i + 1 < len && i + 2 < len && str[i + 1] == 'X' && str[i + 2] == 'X'){
                    ans[pos++] = i + 1;
                }
                else if(i - 2 >= 0 && i - 1 >= 0 && str[i - 2] == 'X' && str[i - 1] == 'X'){
                    ans[pos++] = i + 1;
                }
                else if(check()){
                    ans[pos++] = i + 1;
                }
                str[i] = '.';
            }
        }
    }
    int main(){
        int T, Case = 1;
        getSG();
        scanf("%d", &T);
        while(T--){
            scanf("%s", str);
            solve();
            printf("Case %d:", Case++);
            if(pos == 0) printf(" 0
    ");
            else{
                for(int i = 0; i < pos; i++){
                    printf(" %d", ans[i]);
                }
                printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    orcle id和执行计划(转)
    mysql 授权
    nginx+php 安装手册
    为 MySQL 增加 HTTP/REST 客户端:MySQL UDF 函数 mysql-udf-http 1.0 发布
    Nginx提示502和504错误的解决方案
    error while loading shared libraries: xxx.so.x"错误的原因和解决办法
    lnmp memcache出问题
    Nginx下实现pathinfo及ThinkPHP的URL Rewrite模式支持
    Nginx代理与负载均衡配置与优化
    curl+ post/get 提交
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9716122.html
Copyright © 2011-2022 走看看