HDU 3683 Gomoku (枚举+BFS)

题目大意:给一个五子棋,判断能否在三步内赢棋。

分析:

一步赢棋,枚举下棋位置看是否有5子出现

两步对手赢棋,对手有至少两个位置下棋后可以出现5子

三步赢棋,枚举当前己方下棋点,然后判断会不会出现至少两个位置下棋后可以出现5子,这里还得注意枚举的己方下棋后,对手不能出现(1)的情况。

#include <iostream>#include <cstring>using namespace std;int a[20][20];bool inmap(int x,int y,int op){return x>=0&&x<15&&y>=0&&y<15&&a[x][y]==op;}int dir[4][2]={1,0,0,1,1,1,-1,1};int bfs(int x,int y,int op){for(int i=0;i<4;i++){int sum=1;int xx=x+dir[i][0];int yy=y+dir[i][1];while(inmap(xx,yy,op)){xx+=dir[i][0];yy+=dir[i][1];sum++;}xx=x-dir[i][0];yy=y-dir[i][1];while(inmap(xx,yy,op)){xx-=dir[i][0];yy-=dir[i][1];sum++;}if(sum>=5) return sum;}return -1;}bool gao1(int op,int &x,int &y){for(int i=0;i<15;i++){for(int j=0;j<15;j++){if(a[i][j]==-1){int ans=bfs(i,j,op);if(ans>=5){x=i,y=j;return true;}}}}return false;}bool gao2(int op){int sum=0;for(int i=0;i<15;i++){for(int j=0;j<15;j++){if(a[i][j]==-1){int ans=bfs(i,j,op);if(ans>=5)sum++;if(sum>=2) return true;}}}return false;}bool gao3(int op,int &x,int &y){for(int i=0;i<15;i++){for(int j=0;j<15;j++){if(a[i][j]==-1){a[i][j]=op;if(!gao1(1-op,x,y)&&gao2(op)){x=i,y=j;return true;}a[i][j]=-1;}}}return false;}int main(){int n;while(cin>>n&&n){memset(a, -1, sizeof(a));int sum1=0, sum2=0, x, y, op, c;for(int i=0; i<n; i++){cin>>x>>y>>c;a[x][y]=c;if(c==1)sum1++;elsesum2++;}if(sum1==sum2)op=1;else if(sum1==sum2+1)op=0;else{cout<<"Invalid."<<endl;continue;}if(gao1(op,x,y)){if(op==1)cout<<"Place black at ("<<x<<","<<y<<") to win in 1 move."<<endl;elsecout<<"Place white at ("<<x<<","<<y<<") to win in 1 move."<<endl;}else if(gao2(1-op))cout<<"Lose in 2 moves."<<endl;else if(gao3(op,x,y)){if(op==1)cout<<"Place black at ("<<x<<","<<y<<") to win in 3 moves."<<endl;elsecout<<"Place white at ("<<x<<","<<y<<") to win in 3 moves."<<endl;}elsecout<<"Cannot win in 3 moves."<<endl;}return 0;}

,如果可以,我真想和你一直旅行。

HDU 3683 Gomoku (枚举+BFS)

相关文章:

你感兴趣的文章:

标签云: