zoukankan      html  css  js  c++  java
  • HDU 3683 模拟&搜索

    给出五子棋残局,推断三步内能否分出胜负,玩家为当前该走旗子的颜色,下一步为白棋或黑棋不定。

    依照顺序推断就可以:

    1:推断棋盘是否合法,并确定玩家颜色

    2:推断当前玩家颜色是否有一个必胜点,有玩家则在第一步胜

    3:推断还有一方在当前是否有两个必胜点,若有,则玩家在第二步失败

    4:BFS出玩家是否存在此方案:随意放置一个位置的前提下,还有一方没有必胜点,且玩家有两个必胜点,则玩家在第三步胜

    5:否则3步内无法分出胜负


    #include "stdio.h"
    #include "string.h"
    
    int dir[4][2]={{-1,0},{-1,1},{0,1},{1,1}};
    
    int map[21][21];
    int ans_x,ans_y;
    
    int ok1(int key)
    {
        int i,j,x,y,k,sum;
        for (i=0;i<15;i++)
            for (j=0;j<15;j++)
            if (map[i][j]==-1)
            {
                for (k=0;k<4;k++)
                {
                    x=i; y=j; sum=1;
                    while (1)
                    {
                        x+=dir[k][0];
                        y+=dir[k][1];
                        if (x<0 || x>=15 || y<0 || y>=15) break;
                        if (map[x][y]!=key) break;
                        sum++;
                    }
                    x=i;y=j;
                    while (1)
                    {
                        x-=dir[k][0];
                        y-=dir[k][1];
                        if (x<0 || x>=15 || y<0 || y>=15) break;
                        if (map[x][y]!=key) break;
                        sum++;
    
                    }
                    if (sum>=5) { ans_x=i; ans_y=j; return 1;}
                }
            }
        return -1;
    }
    
    int ok2(int key)
    {
        int i,j,k,x,y,sum,ok;
        ok=0;
        for (i=0;i<=14;i++)
            for (j=0;j<=14;j++)
            if (map[i][j]==-1)
            {
                for (k=0;k<4;k++)
                {
                    sum=1;
                    x=i; y=j;
                    while (1)
                    {
                        x+=dir[k][0];
                        y+=dir[k][1];
                        if (x<0 || x>=15 || y<0 || y>=15) break;
                        if (map[x][y]!=key) break;
                        sum++;
                    }
                    x=i; y=j;
                    while (1)
                    {
                        x-=dir[k][0];
                        y-=dir[k][1];
                        if (x<0 || x>=15 || y<0 || y>=15) break;
                        if (map[x][y]!=key) break;
                        sum++;
                    }
                    if (sum>=5) {ok++;break;}
                }
                if (ok==2) return 1;
            }
            return -1;
    }
    
    
    int bfs(int key)
    {
        int i,j;
        for (i=0;i<15;i++)
            for (j=0;j<15;j++)
            if (map[i][j]==-1)
            {
                map[i][j]=key;
                if (ok1(1-key)==-1 && ok2(key)==1)
                {
                ans_x=i; ans_y=j;
                return 1;
                }
                map[i][j]=-1;
            }
        return -1;
    }
    
    int main()
    {
        int n,i,a,b,c,blk,wt,first,ans;
        while (scanf("%d",&n)!=EOF)
        {
            if (n==0) break;
    
            blk=wt=0;
            memset(map,-1,sizeof(map));
            for (i=1;i<=n;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                map[a][b]=c;
                if (c==1) blk++; else wt++;
            }
    
            if (blk==wt) first=1;
            else
                if (blk==wt+1) first=0;
            else
            {
                printf("Invalid.
    ");
                continue;
            }
    
            ans=ok1(first); // 第一步存在必胜点
            if (ans==1)
            {
                printf("Place ");
                if (first==1) printf("black "); else printf("white ");
                printf("at (%d,%d) to win in 1 move.
    ",ans_x,ans_y);
                continue;
            }
    
            ans=ok2(1-first); // 还有一方存在两个必胜点
            if (ans==1)
            {
                printf("Lose in 2 moves.
    ");
                continue;
            }
    
            ans=bfs(first); // 搜索是否存在第三步定胜负
    
            if (ans==1)
            {
                printf("Place ");
                if (first==1) printf("black "); else printf("white ");
                printf("at (%d,%d) to win in 3 moves.
    ",ans_x,ans_y);
                continue;
            }
            else
                printf("Cannot win in 3 moves.
    ");
    
        }
        return 0;
    
    }
    


  • 相关阅读:
    1002. A+B for Polynomials
    1010. 一元多项式求导
    BZOJ3569
    BZOJ3224
    loj2291. 「THUSC 2016」补退选
    平衡树入门
    高斯消元入门
    写手vector
    矩阵乘法入门
    母函数入门
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4294303.html
Copyright © 2011-2022 走看看