题目描述 Description
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● | ○ | ● | |
○ | ● | ○ | ● |
● | ○ | ● | ○ |
○ | ● | ○ |
输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description
用最少的步数移动到目标棋局的步数。
样例输入 Sample Input
BWBO
WBWB
BWBW
WBWO
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
hi
package testccf;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.Stack;
public class wikioi1004 {
//为了保存移动方法,创建一个data类,before表示移动的前一步,<span style="font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, 微软雅黑, 黑体, sans-serif;">howToMoveComment为了描述如何移动</span>
static class data {
data before;
ArrayList<Character> map;
String howToMoveComment;
public data(data before,ArrayList<Character> map,String howToMoveComment) {
this.before = before;
this.map = map;
this.howToMoveComment = howToMoveComment;
}
}
static void showList(ArrayList<Character> list) {
int n=0;
for(Character c:list) {
System.out.print(c);
n++;
if(n>=4) {
n=0;
System.out.println();
}
}
}
//判断是否达到目标棋局
static boolean isFinishMap(ArrayList<Character> map) {
//左上到右下斜角
if(map.get(0).charValue()==map.get(5).charValue()) {
if(map.get(5).charValue()==map.get(10).charValue()){
if(map.get(10).charValue()==map.get(15).charValue()) {
return true;
}
}
}
//右上到左下斜角
if(map.get(3).charValue()==map.get(6).charValue()) {
if(map.get(6).charValue()==map.get(9).charValue()){
if(map.get(9).charValue()==map.get(12).charValue()) {
return true;
}
}
}
//横线
for(int i=0;i<3;i++) {
if(map.get(i*4).charValue()==map.get(i*4+1).charValue()) {
if(map.get(i*4+1).charValue()==map.get(i*4+2).charValue()) {
if(map.get(i*4+2).charValue()==map.get(i*4+3).charValue()) {
return true;
}
}
}
}
//竖线
for(int i=0;i<3;i++) {
if(map.get(i).charValue()==map.get(i+4).charValue()) {
if(map.get(i+4).charValue()==map.get(i+8).charValue()) {
if(map.get(i+8).charValue()==map.get(i+12).charValue()) {
return true;
}
}
}
}
return false;
}
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
ArrayList<Character> list = new ArrayList<>();
//BFS的队列
LinkedList<data> queue = new LinkedList<>();
for(int i=0;i<4;i++) {
String line = scanner.next();
for(int j=0;j<4;j++) {
list.add(line.charAt(j));
}
}
data first = new data(null,list,null);
queue.add(first);
boolean hasAns = true;
//<span style="font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, 微软雅黑, 黑体, sans-serif;">下面开始BFS </span>
<span style="font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, 微软雅黑, 黑体, sans-serif;"> while(!isFinishMap(queue.getLast().map)) {</span>
ArrayList<Character> nowMap = queue.getFirst().map;
for(int i=0;i<nowMap.size();i++) {
Character ch = nowMap.get(i);
if(ch.charValue()=='O') {
int h = i/4;
int l = i%4;
if((h-1)>=0) {
ArrayList<Character> newMap = new ArrayList<>(nowMap);
newMap.set(i, newMap.get((h-1)*4+l));
newMap.set((h-1)*4+l, 'O');
queue.add(new data(queue.getFirst(),newMap,"第"+(h-1)+"行"+"第"+l+"列移动到第"+h+"行第"+l+"列"));
}
if((h+1)<4) {
ArrayList<Character> newMap = new ArrayList<>(nowMap);
newMap.set(i, newMap.get((h+1)*4+l));
newMap.set((h+1)*4+l, 'O');
queue.add(new data(queue.getFirst(),newMap,"第"+(h+1)+"行"+"第"+l+"列移动到第"+h+"行第"+l+"列"));
}
if((l-1)>=0) {
ArrayList<Character> newMap = new ArrayList<>(nowMap);
newMap.set(i, newMap.get(h*4+l-1));
newMap.set(h*4+l-1, 'O');
queue.add(new data(queue.getFirst(),newMap,"第"+h+"行"+"第"+(l-1)+"列移动到第"+h+"行第"+l+"列"));
}
if((l+1)<4) {
ArrayList<Character> newMap = new ArrayList<>(nowMap);
newMap.set(i, newMap.get(h*4+l+1));
newMap.set(h*4+l+1, 'O');
queue.add(new data(queue.getFirst(),newMap,"第"+h+"行"+"第"+(l+1)+"列移动到第"+h+"行第"+l+"列"));
}
}
}
queue.remove();
if(queue.isEmpty()) {System.out.print("No Answer!");hasAns=false;break;}
}
Stack<data> stack = new Stack<>();
data d = queue.getLast();
while(d!=null) {
stack.push(d);
d = d.before;
}
System.out.println("移动了"+(stack.size()-1)+"步:");
while(!stack.isEmpty()) {
data tmpd = stack.pop();
showList(tmpd.map);
if(!stack.isEmpty()) {
String tmp = stack.peek().howToMoveComment;
if(tmp!=null) {
System.out.println(tmp);
}
}
System.out.println("----------------");
}
}
}
代码输入:
BWBO
WBWB
BWBW
WBWO
WBWB
BWBW
WBWO
代码输出:
移动了6步:
BWBO
WBWB
BWBW
WBWO
第1行第3列移动到第0行第3列
----------------
BWBB
WBWO
BWBW
WBWO
第2行第3列移动到第1行第3列
----------------
BWBB
WBWW
BWBO
WBWO
第3行第2列移动到第3行第3列
----------------
BWBB
WBWW
BWBO
WBOW
第3行第3列移动到第2行第3列
----------------
BWBB
WBWW
BWBW
WBOO
第3行第1列移动到第3行第2列
----------------
BWBB
WBWW
BWBW
WOBO
第3行第2列移动到第3行第3列
----------------
BWBB
WBWW
BWBW
WOOB
----------------
BWBO
WBWB
BWBW
WBWO
第1行第3列移动到第0行第3列
----------------
BWBB
WBWO
BWBW
WBWO
第2行第3列移动到第1行第3列
----------------
BWBB
WBWW
BWBO
WBWO
第3行第2列移动到第3行第3列
----------------
BWBB
WBWW
BWBO
WBOW
第3行第3列移动到第2行第3列
----------------
BWBB
WBWW
BWBW
WBOO
第3行第1列移动到第3行第2列
----------------
BWBB
WBWW
BWBW
WOBO
第3行第2列移动到第3行第3列
----------------
BWBB
WBWW
BWBW
WOOB
----------------