CQOI2013 棋盘游戏

本文深入解析了在特定棋盘游戏中,如何运用博弈论中的搜索策略来确定最优行动方案。通过对比双方角色的不同移动范围,文章阐述了如何设定游戏规则以避免平局,并详细解释了在对抗搜索中如何通过min-max算法实现一方追求最小步数胜利,另一方则尽力延长游戏进程的策略。代码示例使用C++实现,展示了具体搜索函数的递归调用过程。

题目链接:戳我

emmmm因为B的活动范围比A广,所以只要不是第一步被A吃掉,终究会赢得胜利的(根本不会有平局嘛)

上面那个结论一定要先确定好,不知道结果的话没法对抗搜索的。

然后就.....我们的目的是让B尽快地赢,A尽可能地多跑一会儿,所以前者取min后者取max。

QAQ 但是讲道理应该步数不应该是2*n以内嘛.....我也不太明白,等dalao们CTS/APIO回来之后问问他们我再update吧......

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define MAXN 25
using namespace std;
int n,m,black,white,r1,r2,c1,c2;
int sum[MAXN][MAXN][MAXN][MAXN][2][60];
int move_x[4]={-1,1,0,0},move_y[4]={0,0,-1,1};
int move_x2[8]={-1,-2,1,2,0,0,0,0},move_y2[8]={0,0,0,0,-1,-2,1,2};
inline int search(int r1,int c1,int r2,int c2,int op,int cnt)
{  
    if(cnt>3*n)  return 0x3f3f3f3f;
    if(sum[r1][c1][r2][c2][op][cnt]) return sum[r1][c1][r2][c2][op][cnt]; 
    // printf("[%d %d] [%d %d] %d\n",r1,c1,r2,c2,op);                                     
    if(r1==r2&&c1==c2)
    {
        if(op==0) sum[r1][c1][r2][c2][op][cnt]=0;
        else sum[r1][c1][r2][c2][op][cnt]=0x3f3f3f3f;
        // printf("bingo! %d\n",sum[r1][c1][r2][c2][op][cnt]);
        return sum[r1][c1][r2][c2][op][cnt];
    }
    int cur_ans;
    if(op==0)
    {
        cur_ans=0;
        for(int i=0;i<=3;i++)
        {
            int xx=r1+move_x[i];
            int yy=c1+move_y[i];
            if(xx<1||xx>n||yy<1||yy>n) continue;
            int cur=search(xx,yy,r2,c2,1,cnt+1);
            cur_ans=max(cur_ans,cur);
        }
    }
    else 
    {
        cur_ans=0x3f3f3f3f;
        for(int i=0;i<=7;i++)
        {
            int xx=r2+move_x2[i];
            int yy=c2+move_y2[i];
            if(xx<1||xx>n||yy<1||yy>n) continue;
            int cur=search(r1,c1,xx,yy,0,cnt+1);
            cur_ans=min(cur_ans,cur);
        }
    }
    // printf("%d\n",sum[r1][c1][r2][c2][op][cnt]);
    sum[r1][c1][r2][c2][op][cnt]=++cur_ans;
    return cur_ans;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    // freopen("ce.out","w",stdout);
    #endif
    scanf("%d%d%d%d%d",&n,&r1,&c1,&r2,&c2);
    if(abs(r1-r2)+abs(c1-c2)<=1) printf("WHITE 1\n");
    else 
    {
        printf("BLACK ");
        int ans=search(r1,c1,r2,c2,0,0);
        printf("%d\n",ans);
    }
    return 0;
}

转载于:https://www.cnblogs.com/fengxunling/p/10860264.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值