codevs 1004 四子连棋

          在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步, 黑白双方交替走棋,任意一方可以先走 ,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。 用最少的步数移动到目标棋局的步数。
 
 

        一道深搜题,很早以前写的了,可能颇显愚笨,还望笑谅。

#include   
int map[5][5],ans,flag;  
int dx[5]={0,-1,1,0,0};  
int dy[5]={0,0,0,-1,1};  
inline void dfs(int ch,int deep);  
inline void swap(int &a,int &b){  
    int t=a; a=b; b=t;  
}  
inline bool check(){  
    for(int k=1;k<=4;k++){  
        if(map[k][1]==map[k][2]&&  
            map[k][2]==map[k][3]&&  
                map[k][3]==map[k][4]) return 1;  
        if(map[1][k]==map[2][k]&&  
            map[2][k]==map[3][k]&&  
                map[3][k]==map[4][k]) return 1;  
    }  
    if(map[1][1]==map[2][2]&&  
        map[2][2]==map[3][3]&&  
            map[3][3]==map[4][4]) return 1;  
    if(map[1][4]==map[2][3]&&  
        map[2][3]==map[3][2]&&  
            map[3][2]==map[4][1]) return 1;  
    return 0;  
}  
inline void temp(int ch,int deep,int x,int y){  
    for(int i=1;i<=4;i++)  
        if(map[x+dx[i]][y+dy[i]]==ch&&  
            x+dx[i]>0&&y+dy[i]>0&&  
                x+dx[i]<5&&y+dy[i]<5){  
            swap(map[x+dx[i]][y+dy[i]],map[x][y]);  
            dfs(ch,deep+1);  
            swap(map[x+dx[i]][y+dy[i]],map[x][y]);  
        }  
}  
inline void dfs(int ch,int deep){  
    int next=ch==1?0:1;  
    if(flag) return;  
    if(deep==ans){  
        if(check()) flag=1;  
        return;  
    }  
    for(int i=1;i<=4;i++)  
        for(int j=1;j<=4;j++)  
            if(map[i][j]==-1) temp(next,deep,i,j);  
}  
int main(){  
    for(int i=1;i<=4;i++)  
        for(int j=1;j<=4;j++){  
            char a;  
            scanf(" %c",&a);  
            if(a=='B') map[i][j]=1;  
            if(a=='O') map[i][j]=-1;  
        }  
    for(ans=1;flag==0;ans++){  
        dfs(0,0);  
        if(flag) break;  
        dfs(1,0);  
        if(flag) break;  
    }  
    printf("%d\n",ans);  
    return 0;  
}  


你可能感兴趣的:(C++)