zoukankan      html  css  js  c++  java
  • CodeForces-63E Sweets Game 博弈论,状态压缩,记忆化搜索

    CodeForces-63E Sweets Game 博弈论,状态压缩,记忆化搜索

    题意

    给定一个长度为3的正六边形的棋盘,若为(O) 则表示这个位置有糖果。

    两人轮流吃糖果,每次可以选择在一条直线上的任意个糖果吃,不能吃的人为败者。

    Input

      . . .
     . . O .
    . . O O .
     . . . .
      . . .
    

    Output

    Lillebror
    

    分析

    显然是一个博弈问题,但是由于规模非常小,可以考虑直接爆搜。

    首先对棋盘的每个位置标号,若位置(i)(O) ,就用一个二进制数的第(i)(1)表示出来。

    搜索过程中,如果转移过去的状态不是当前状态的子集,显然是不行的,break就可。

    假设转移过去的(O) 标号是(k) ,那么只需(tmp ^= 1 << k) 来转移,表示拿走了这个糖果

    注意实现要加括号((tmp & (1 << k)) == 0)

    代码

    const int dx[] = { 0,1,1 };
    const int dy[] = { 2,1,-1 };
    
    int mp[15][15];
    int dp[1 << 21];
    
    
    int solve(int mask) {
        if (!mask) return 0;
        if (dp[mask] != -1) return dp[mask];
        dp[mask] = 1;
        for(int x = 0;x < 5;x++)
            for (int y = 0; y < 9; y++) {
                if (mp[x][y] == -1) continue;
                for (int i = 0; i < 3; i++) {
                    int tmp = mask;
                    for (int xx = x, yy = y; xx < 5 && xx >= 0 && yy < 9 && yy >= 0; xx += dx[i], yy += dy[i]) {
                        if (mp[xx][yy] == -1) break;
                        int k = mp[xx][yy];
                        if ((tmp & (1 << k)) == 0) break;
                        tmp ^= 1 << k;
                        dp[mask] &= solve(tmp);
                    }
                }
            }
        return dp[mask] ^= 1;
    }
    
    
    int main() {
        memset(dp, -1, sizeof dp);
        memset(mp, -1, sizeof mp);
        int k = 0;
        for (int i = 2; i <= 6; i += 2) mp[0][i] = k++;
        for (int i = 1; i <= 7; i += 2) mp[1][i] = k++;
        for (int i = 0; i <= 8; i += 2) mp[2][i] = k++;
        for (int i = 1; i <= 7; i += 2) mp[3][i] = k++;
        for (int i = 2; i <= 6; i += 2) mp[4][i] = k++;
        int mask = 0;
        string s;
        for (int i = 0; i < 5; i++) {
            getline(cin, s);
            for (int j = 0; j < s.length(); j++)
                if (s[j] == 'O') mask |= 1 << mp[i][j];
        }
        if (solve(mask)) puts("Karlsson");
        else puts("Lillebror");
    }
    
  • 相关阅读:
    创建网关项目(Spring Cloud Gateway)
    调用Consul服务(消费服务)
    创建调用Consul的客户端项目
    注册服务到服务中心(Consul)
    安装Consul服务中心
    创建Spring Boot微服务项目
    React学习之State
    React学习及实例开发(一)——开始
    React Native学习(十)—— 生命周期
    【小记事】电脑命令行开WiFi
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13618872.html
Copyright © 2011-2022 走看看