【codevs1004】四子连棋

今天复习一下bfs,顺便把之前一直没a的四字连棋做了一下

这个题,我认为难点就在于移动棋子的一系列操作,太长了。

ps:不知道为啥,洛谷和codevs同时不待见getchar,在自己从codevs那里拿了了些数据,手动测了一下,发现都对了,好迷

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct in
{
    int a[6][6];
    int as,ne;
}ter,qaq;
int ans,h[4]={-1,0,1,0},z[4]={0,1,0,-1};
bool ha[(100003)<<1];
char s[5];
queue<in>qwq;
inline int hash(in x)
{
    int re=1,tot=1;
    for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++)
            re=re*3+x.a[i][j];
    re%=100003;
    return re;
}
inline bool cha(int i,int j,int k,int l)
{
    if(i==j&&j==k&&k==l&&l==i)
        return 1;
    return 0;
}
inline bool pan()
{
    for(int i=1;i<=4;i++)
    {
        if(cha(qaq.a[i][1],qaq.a[i][2],qaq.a[i][3],qaq.a[i][4]))
            return 1;
        if(cha(qaq.a[1][i],qaq.a[2][i],qaq.a[3][i],qaq.a[4][i]))
            return 1;
    }
    if(cha(qaq.a[1][1],qaq.a[2][2],qaq.a[3][3],qaq.a[4][4]))
        return 1;
    if(cha(qaq.a[1][4],qaq.a[2][3],qaq.a[3][2],qaq.a[4][1]))
        return 1;
    return 0;
}
inline bool can(int x,int y)
{
    if(x<=0||x>4||y<=0||y>4)
        return 0;
    if(qaq.a[x][y]==qaq.ne)
        return 1;
    return 0;
}
inline void move(int x,int y)
{
    for(int i=0;i<4;i++)
    {
        int nx=x+h[i],ny=y+z[i];
        if(can(nx,ny))
        {
            in owo=qaq;
            swap(owo.a[x][y],owo.a[nx][ny]);
            if(!ha[hash(owo)])
            {
                owo.as=qaq.as+1;
                if(qaq.ne==1)
                    owo.ne=0;
                if(qaq.ne==0)
                    owo.ne=1;
                qwq.push(owo);
            }
        }
    }
}
inline void bfs()
{
    while(!qwq.empty())
    {
        qaq=qwq.front();
        if(pan())
        {
            ans=qaq.as;
            return;
        }
        ha[hash(qaq)]=1;
        qwq.pop();
        for(int i=1;i<=4;i++)
            for(int j=1;j<=4;j++)
                if(qaq.a[i][j]==2)
                    move(i,j);
    }
}
int main()
{
    for(int i=1;i<=4;i++)
    {
        scanf("%s",s+1);        
        for(int j=1;j<=5;j++)
        {
            
            if(s[j]=='B')
                ter.a[i][j]=0;
            else if(s[j]=='W')
                ter.a[i][j]=1;
            else if(s[j]=='O')
                ter.a[i][j]=2;
        }
    }
        
    ter.as=0,ter.ne=0;
    qwq.push(ter);
    ter.ne=1;
    qwq.push(ter);
    bfs();
    if(!ans)
        ans=1;
    printf("%d",ans);
}

 

posted @ 2017-10-12 20:54  那一抹落日的橙  阅读(283)  评论(0编辑  收藏  举报