uvaoj 1085 - House of Cards

题解:
裸的最大最小搜索,alpha beta 剪枝
总结:
1.对着刘汝佳的代码写得,汝佳哥代码的亮点还是很多
2.因为最后只需要两个选手得分的差值,所以直接算出A选手得分 减去 B选手得分的大小,如果不符合则取反,而计算分数的时候可以直接把A得分算为正(加),B得分算为负(剪),A + (-B)的形式我认为正是数学统一思想的体现
matrix67这样介绍的负数
而且很好的减少了代码量,犯错误的概率
3.往上码牌的时候,也是用到了这种思想,用两张横着的牌代替一张横着的牌
4.争取培养一种将现实问题转化为编程问题的思维方式

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
#define MAXN 20
#define MAXM 10
#define INF 0x3f3f3f3f
int deck[MAXN * 2],n;
char s[MAXM];
const int UP = 0,FLOOR = 1,DOWN = 2;
struct State
{
    int type[MAXN],card[MAXN],hold[2];
    int pos,score;
    State()
    {
        for(int i = 0;i < 8;i++)
        {
            card[i] = deck[i];
            if(i & 1)type[i] = DOWN;
            else type[i] = UP;
        }
        pos = 8;
        hold[0] = hold[1] = score = 0;
    }
    State child()const
    {
        State s(*this);
        s.pos++;
        return s;
    }
    void expand(vector<State> & vec,int player)const
    {
        int cur = deck[pos];
        if(!hold[player])
        {
            State s = child();
            s.hold[player] = cur;
            vec.push_back(s);
        }
        for(int i = 0;i < 7;i++)if(type[i] == DOWN && type[i + 1] == UP)
        {
            State s = child();
            s.score += getScore(card[i],card[i + 1],cur);
            s.type[i] = s.type[i + 1] = FLOOR;
            s.card[i] = s.card[i + 1] = cur;
            vec.push_back(s);

            if(hold[player])
            {
                State s = child();
                s.score += getScore(card[i],card[i + 1],hold[player]);
                s.type[i] = s.type[i + 1] = FLOOR;
                s.card[i] = s.card[i + 1] = hold[player];
                s.hold[player] = cur;
                vec.push_back(s);
            }
        }
        if(!hold[player])return;
        for(int i = 0;i < 7;i++)if(type[i] == FLOOR && type[i + 1] == FLOOR && card[i] == card[i + 1])
        {
            State s = child();
            s.score += getScore(card[i],cur,hold[player]);
            s.type[i] = UP;s.type[i + 1] = DOWN;
            s.card[i] = cur;s.card[i + 1] = hold[player];
            s.hold[player] = 0;
            vec.push_back(s);

            swap(s.card[i],s.card[i + 1]);
            vec.push_back(s);
        }
    }
    int getScore(int a,int b,int c)const
    {
        int cur = abs(a) + abs(b) + abs(c);
        int cnt = (a > 0 ? 1 : -1) + (b > 0 ? 1 : -1) + (c > 0 ? 1 : -1);
        return cnt > 0 ? cur : -cur;
    }
    bool isfind()
    {
        if(pos == n * 2)
        {
            score += hold[0] + hold[1];
            hold[0] = hold[1] = 0;
            return true;
        }
        return false;
    }
};
int alphabeta(State& s,int player,int alpha,int beta)
{
    if(s.isfind())return s.score;
    vector<State>vec;
    s.expand(vec,player);
    for(int i = 0;i < vec.size();i++)
    {
        int v = alphabeta(vec[i],!player,alpha,beta);
        if(!player)alpha = max(v,alpha);
        else beta = min(v,beta);
        if(beta <= alpha)break;
    }
    return !player ? alpha : beta;
}
int main()
{
    int kase = 0;
    while(scanf("%s",s) && s[0] != 'E')
    {
        scanf("%d",&n);
        for(int i = 0;i < 2 * n;i++)
        {
            char ch;
            scanf("%d%c",&deck[i],&ch);
            if(ch == 'B')deck[i] = -deck[i];
        }
        int player = deck[0] > 0 ? 0 : 1;
        State init;
        int score = alphabeta(init,player,-INF,INF);
        if(s[0] == 'B')score = -score;
        printf("Case %d: ", ++kase);
        if(score == 0)puts("Axel and Birgit tie");
        else if(score > 0)printf("%s wins %d\n",s,score);
        else printf("%s loses %d\n",s,-score);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值