http://codevs.cn/problem/1004/
思路:
我的思路是,将棋盘用一个17个大小的字符串表示,最后一位表示黑子(白子)执棋。使用map<string,bool>判断某一棋盘是否已经存在了。
需要注意的是,棋盘的移动中,左右移动需要额外判断一下是不是边界棋子,比如第3号棋子的右边4号棋子其实是下一行的起始棋子。
#include<iostream>
#include<cmath>
#include<queue>
#include<string>
#include<map>
using namespace std;
string chess0="";
map<string,bool> mp;
queue<string>q;
bool target(string str){
//判断四行
for(int i=0;i<16;i+=4){
char top=str[i+0];
if(top==str[i+1]&&top==str[i+2]&&top==str[i+3])return true;
}
//判断四列
for(int i=0;i<4;i++){
char top=str[i];
if(top==str[i+4]&&top==str[i+8]&&top==str[i+12])return true;
}
char top=str[0];
if(top==str[5]&&top==str[10]&&top==str[15])return true;
top=str[3];
if(top==str[6]&&top==str[9]&&top==str[12])return true;
return false;
}
void show(string &str){
// cout<<endl;
// for(int i=0;i<16;i+=4){
// for(int j=0;j<4;j++){
// cout<<str[i+j];
// }cout<<endl;
// }
// cout<<str[16]<<endl;
}
bool move(string str){
// cout<<"*****************************";
show(str);
// cout<<"*****************************"<<endl;
char b=str[16];
for(int i=0;i<16;i++){
if(str[i]=='O'){
if(i-4>=0&&str[i-4]==b){//上
string new_chess=str;
new_chess[i]=b;
new_chess[i-4]='O';
if(b=='B')new_chess[16]='W';
else new_chess[16]='B';
if(mp.count(new_chess)==0){
mp[new_chess]=false;
if(target(new_chess)){
show(new_chess);
return true;
}
q.push(new_chess);
}
show(new_chess);
}
if(i-1>=0&&(i-1)%4!=3&&str[i-1]==b){//左
string new_chess=str;
new_chess[i]=b;
new_chess[i-1]='O';
if(b=='B')new_chess[16]='W';
else new_chess[16]='B';
if(mp.count(new_chess)==0){
mp[new_chess]=false;
if(target(new_chess)){
show(new_chess);
return true;
}
q.push(new_chess);
}
show(new_chess);
}
if(i+4<16&&str[i+4]==b){//下
string new_chess=str;
new_chess[i]=b;
new_chess[i+4]='O';
if(b=='B')new_chess[16]='W';
else new_chess[16]='B';
if(mp.count(new_chess)==0){
mp[new_chess]=false;
if(target(new_chess)){
show(new_chess);
return true;
}
q.push(new_chess);
}
show(new_chess);
}
if(i+1<16&&(i+1)%4!=0&&str[i+1]==b){//右
string new_chess=str;
new_chess[i]=b;
new_chess[i+1]='O';
if(b=='B')new_chess[16]='W';
else new_chess[16]='B';
if(mp.count(new_chess)==0){
mp[new_chess]=false;
if(target(new_chess)){
show(new_chess);
return true;
}
q.push(new_chess);
}
show(new_chess);
}
}
}
return false;
}
int main(){
//初始化棋盘
string str;
int t=4;
while(t--) {
cin>>str;chess0+=str;
}
mp[chess0+"B"]=false;
mp[chess0+"W"]=false;
int ans=0;
q.push(chess0+"W");
q.push(chess0+"B");
if(target(chess0+"B")||target(chess0+"W")){
cout<<100<<endl;
return 0;
}
while(1){
ans++;
//cout<<ans<<endl<<endl;
int len=q.size();
while(len--){
string top=q.front();q.pop();
if(move(top)){
cout<<ans<<endl;
return 0;
}
}
}
return 0;
}