I. Rake It In

I. Rake It In

题意:两个人玩游戏,k是每个人走的步数,A先走,在一个4x4 的棋盘上选择1个2x2的区域进行求和然后加到总和上,该2x2区域的数字逆时针旋转90度,玩家A上让分数最大,玩家B是让分数最小,输出最后可能的分数。

思路:参考别人的AlphaBeta剪枝算法

代码:

/**
 * ============================
 * @title:    2017nanning
 * @Author:   kuroko
 * @Version:  1.0 
 * @DateTime: 2018-08-24 09:20:15
 * ============================
 */
#include<bits/stdc++.h>
const int inf =(1<<20);
 
using namespace std;
 
int sum;
int k;
int Map[5][5];
 
int rote(int x, int y)
{
    swap(Map[x][y], Map[x + 1][y]);
    swap(Map[x][y + 1], Map[x + 1][y + 1]);
    swap(Map[x][y], Map[x + 1][y + 1]);
    return Map[x][y] + Map[x + 1][y] + Map[x][y + 1] + Map[x + 1][y + 1];
}
 
void rerote(int x, int y)//逆时针旋转90度
{
    swap(Map[x][y], Map[x + 1][y + 1]);
    swap(Map[x][y + 1], Map[x + 1][y + 1]);
    swap(Map[x][y], Map[x + 1][y]);
}
 
int DFS(int sum, int dep, int alpha, int beta)
{
    if(dep == 2 * k)
    {
        return sum;
    }
    //只能三乘三的这块区域可以进行旋转
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            int tmp = DFS(sum + rote(i, j), dep + 1, alpha, beta);
            rerote(i, j);
            //因为我是从dep=0开始的
            if(dep & 1)//
                beta = min(beta, tmp);//最小值
            else
                alpha = max(alpha, tmp);//最大值
                return dep & 1 ? beta : alpha;
        }
    }
    return dep & 1 ? beta : alpha;
}
 
int main()
{
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t--)
    {
        cin >> k;
        for(int i = 0; i < 4; i++)
        {
            for(int j = 0; j < 4; j++)
            {
                cin >> Map[i][j];
            }
        }
        int ans=DFS(sum, 0, -inf, inf);
        cout <<ans<< endl;
    }
 
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/kuroko-ghh/p/9528302.html