题目链接 | 难度等级 | 完成状态 | 完成分数 | 最后编辑时间 | 失误原因(初次提交分数) |
---|---|---|---|---|---|
四子连棋 | ★☆☆☆☆ | 答案正确 | 100 | 2014/12/04 19:42:46 | 看漏条件(45) |
在4*4的棋盘,黑白双方交替走棋,任意一方可以先走,求到四子连棋的最小步数。
1004.cpp代码已折叠
展开折叠内容
|
---|
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int deltaX[4]={0,0,1,-1},deltaY[4]={1,-1,0,0}; char oC[2]={'B','W'}; class state { private: char a[5][5]; public: const bool isEnd() const { for(int i=1;i<=4;++i) { int xEnd=1,yEnd=1; for(int j=2;j<=4;++j) { if(a[j][i]!=a[j-1][i]||a[j][i]=='O') xEnd=0; if(a[i][j]!=a[i][j-1]||a[i][j]=='O') yEnd=0; } if(xEnd||yEnd) return 1; } int d1End=1,d2End=1; for(int i=2;i<=4;++i) { if(a[i][i]!=a[i-1][i-1]||a[i][i]=='O') d1End=0; if(a[i][5-i]!=a[i-1][5-i+1]||a[i][5-i]=='O') d2End=0; } if(d1End||d2End) return 1; return 0; } void init() { for(int i=1;i<=4;++i) { for(int j=1;j<=4;++j) cin>>a[i][j]; } } void p() { for(int i=1;i<=4;++i) { for(int j=1;j<=4;++j) cout<<a[i][j]; cout<<endl; } } inline const int getId() const { int p=0,u=1; for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) { if(a[i][j]=='B') p+=1*u; if(a[i][j]=='W') p+=2*u; u*=3; } return p; } inline char *at(const int& x,const int& y) { if(x<1||x>4||y<1||y>4) return NULL; return &a[x][y]; } }; int stepL; short stepD[50000000]={}; const bool dfs(state now,const int &step,bool color) { //now.p(); if(step>stepL) return 0; if(now.isEnd()) return 1; int nid=now.getId(); if(stepD[nid]&&stepD[nid]<step) return 0; stepD[nid]=step; for(int i=1;i<=4;++i) { for(int j=1;j<=4;++j) { for(int dir=0;dir<4;++dir) { int newi=i+deltaX[dir],newj=j+deltaY[dir]; if(now.at(newi,newj)==NULL) continue; if(*now.at(newi,newj)!='O'||*now.at(i,j)!=oC[color])//第一次写的时候没有看到要交替下棋 continue; swap(*now.at(newi,newj),*now.at(i,j)); if(dfs(now,step+1,!color)) return 1; swap(*now.at(newi,newj),*now.at(i,j)); } } } return 0; } state c; int main() { c.init(); for(stepL=1;stepL<=100;++stepL) { if(dfs(c,1,0)||dfs(c,1,1)){ printf("%d",stepL-1); return 0; } } } |