题目链接:http://poj.org/problem?id=1568

题意:给出一个4*4的棋盘,x和o两人轮流放。先放够连续四个的赢。给定一个局面,下一个轮到x放。问x是否有必胜策略?若有,输出能够赢的最小的坐标?

思路:(1)Maxfind(Min):每次放x,若得到的Max大于等于Min,则直接返回Max。因为Minfind要用这个Max更新Min,若x放置之后能够得到一个比Min大的,显然这样放最好;因为Min无法用Max更新;

(2)Minfind(Max)类似;

(3)因此,枚举第一个人放的位置,Minfind,返回的是INF则胜利。

char s[10][10];
int ansX,ansY,chessCnt;

int isOver(int x,int y)
{
    int r[4]={0},c[4]={0},i,j;
    clr(r,0); clr(c,0);
    FOR0(i,4) FOR0(j,4)
    {
        if(s[i][j]=='x') r[i]++,c[j]++;
        if(s[i][j]=='o') r[i]--,c[j]--;
    }
    if(abs(r[x])==4||abs(c[y])==4) return 1;
    int cnt1=0,cnt2=0;
    FOR0(i,4)
    {
        if(s[i][i]=='x') cnt1++;
        if(s[i][3-i]=='x') cnt2++;
        if(s[i][i]=='o') cnt1--;
        if(s[i][3-i]=='o') cnt2--;
    }
    if(abs(cnt1)==4&&x==y||abs(cnt2)==4&&x+y==3) return 1;
    return 0;
}

int Minfind(int,int,int);

int Maxfind(int x,int y,int Min)
{
    int temp,Max=-INF,i,j;
    if(isOver(x,y)) return Max;
    if(chessCnt==16) return 0;
    FOR0(i,4) FOR0(j,4) if(s[i][j]=='.')
    {
        s[i][j]='x';
        chessCnt++;
        temp=Minfind(i,j,Max);
        chessCnt--;
        s[i][j]='.';
        if(temp>Max) Max=temp;
        if(Max>=Min) return Max;
    }
    return Max;
}

int Minfind(int x,int y,int Max)
{
    int temp,Min=INF,i,j;
    if(isOver(x,y)) return Min;
    if(chessCnt==16) return 0;
    FOR0(i,4) FOR0(j,4) if(s[i][j]=='.')
    {
        s[i][j]='o';
        chessCnt++;
        temp=Maxfind(i,j,Min);
        chessCnt--;
        s[i][j]='.';
        if(temp<Min) Min=temp;
        if(Min<=Max) return Min;
    }
    return Min;
}

int check()
{
    int Max=-INF,i,j,temp;
    FOR0(i,4) FOR0(j,4) if(s[i][j]=='.')
    {
        s[i][j]='x';
        chessCnt++;
        temp=Minfind(i,j,Max);
        chessCnt--;
        s[i][j]='.';
        if(temp>Max) Max=temp,ansX=i,ansY=j;
        if(Max==INF) return 1;
    }
    return 0;
}

int main()
{
    char op[5];
    while(scanf("%s",op)&&op[0]!='$')
    {
        int i,j;
        chessCnt=0;
        FOR0(i,4)
        {
            RD(s[i]);
            FOR0(j,4) chessCnt+=s[i][j]!='.';
        }
        if(chessCnt<=4||!check()) puts("#####");
        else printf("(%d,%d)\n",ansX,ansY);
    }
}

POJ 1568 Find the Winning Move(极大极小搜索)的更多相关文章

  1. poj 1568 Find the Winning Move 极大极小搜索

    思路:用极大极小搜索解决这样的问题很方便!! 代码如下: #include <cstdio> #include <algorithm> #define inf 10000000 ...

  2. POJ 1568 Find the Winning Move

    Find the Winning Move 链接 题意: 4*4的棋盘,给出一个初始局面,问先手有没有必胜策略? 有的话输出第一步下在哪里,如果有多个,按(0, 0), (0, 1), (0, 2), ...

  3. poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]

    Find the Winning Move Time Limit: 3000MS   Memory Limit: 32768K Total Submissions: 1286   Accepted:  ...

  4. POJ 1568 极大极小搜索 + alpha-beta剪枝

    极小极大搜索 的个人理解(alpha-beta剪枝) 主要算法依据就是根据极大极小搜索实现的. 苦逼的是,查了两个晚上的错,原来最终是判断函数写错了..瞬间吐血! ps. 据说加一句 if sum & ...

  5. 【迭代博弈+搜索+剪枝】poj-1568--Find the Winning Move

    poj  1568:Find the Winning Move   [迭代博弈+搜索+剪枝] 题面省略... Input The input contains one or more test cas ...

  6. 算法笔记--极大极小搜索及alpha-beta剪枝

    参考1:https://www.zhihu.com/question/27221568 参考2:https://blog.csdn.net/hzk_cpp/article/details/792757 ...

  7. 【poj1568】 Find the Winning Move

    http://poj.org/problem?id=1568 (题目链接) 题意 两人下4*4的井字棋,给出一个残局,问是否有先手必胜策略. Solution 极大极小搜索.. 这里有个强力优化,若已 ...

  8. 极大极小搜索思想+(α/β)减枝 【转自-----https://blog.csdn.net/hzk_cpp/article/details/79275772】

    极大极小搜索,即minimax搜索算法,专门用来做博弈论的问题的暴力. 多被称为对抗搜索算法. 这个搜索算法的基本思想就是分两层,一层是先手,记为a,还有一层是后手,记为b. 这个搜索是认为这a与b的 ...

  9. [CodeVs3196]黄金宝藏(DP/极大极小搜索)

    题目大意:给出n(≤500)个数,两个人轮流取数,每次可以从数列左边或者右边取一个数,直到所有的数被取完,两个人都以最优策略取数,求最后两人所得分数. 显然这种类型的博弈题,第一眼就是极大极小搜索+记 ...

随机推荐

  1. JVM 崩溃 Failed to write core dump解决办法 WINDOWS

    JVM 崩溃 Failed to write core dump解决办法 WINDOWS MIT key words: JVM,崩溃,windows,Failed,core dump,虚拟内存 最近从 ...

  2. O(V*n)的多重背包问题

    多重背包问题: 有n件物品,第i件价值为wi,质量为vi,有c1件,问,给定容量V,求获得的最大价值. 朴素做法: 视为0,1,2,...,k种物品的分组背包 [每组只能选一个] f[i][j]=Ma ...

  3. 【BZOJ】【1048】【HAOI2007】分割矩阵

    DP/记忆化搜索 暴力枚举分割方案?……大概是指数级的?大约是20!的方案= =? 但是我们看到a.b.n的范围都很小……所以不同的状态数只是$10^5$级别的,可以记忆化搜索求解 比较水的一道题…… ...

  4. 【BZOJ】【3522】【POI2014】Hotel

    暴力/树形DP 要求在树上找出等距三点,求方案数,那么用类似Free Tour2那样的合并方法,可以写出: f[i][j]表示以 i 为根的子树中,距离 i 为 j 的点有多少个: g[i][j]表示 ...

  5. [工作积累] NDK通过Java获取package name 和version

    ////////////////////////////////////////////////////////////////////////// //Java code snippet //get ...

  6. HDU 5014Number Sequence

    思路: 对于一个二进制100011: 尽量将填满:填成111111: 然后有一个很好算的方法 gets(n)表示二进制下N有多少位,N^X=(111111)2 X=111111^N; 其实答案可以直接 ...

  7. python 安装 管理包 pip

    2.7的坑里出不来了,现在已经换到3.4了,不存在下列问题. win7下安装pip    http://blog.chinaunix.net/uid-24984661-id-4202194.html ...

  8. Linux中ping命令

    Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地址192.168.1.1试试”. ...

  9. hdu 4764 Stone (巴什博弈,披着狼皮的羊,小样,以为换了身皮就不认识啦)

    今天(2013/9/28)长春站,最后一场网络赛! 3~5分钟后有队伍率先发现伪装了的签到题(博弈) 思路: 与取石头的巴什博弈对比 题目要求第一个人取数字在[1,k]间的某数x,后手取x加[1,k] ...

  10. Android核心分析之十五Android输入系统之输入路径详解

       Android用户事件输入路径 1 输入路径的一般原理 按键,鼠标消息从收集到最终将发送到焦点窗口,要经历怎样的路径,是Android GWES设计方案中需要详细考虑的问题.按键,鼠标等用户消息 ...