13.纵横放火柴游戏
【编程题】(满分34分)
这是一个纵横火柴棒游戏。如图[1.jpg],在3x4的格子中,游戏的双方轮流放置火柴棒。其规则是: 1. 不能放置在已经放置火柴棒的地方(即只能在空格中放置)。 2. 火柴棒的方向只能是竖直或水平放置。 3. 火柴棒不能与其它格子中的火柴“连通”。所谓连通是指两根火柴棒可以连成一条直线, 且中间没有其它不同方向的火柴“阻拦”。
例如:图[1.jpg]所示的局面下,可以在C2位置竖直放置(为了方便描述格子位置,图中左、下都添加了标记), 但不能水平放置,因为会与A2连通。同样道理,B2,B3,D2此时两种方向都不可以放置。但如果C2竖直放置后, D2就可以水平放置了,因为不再会与A2连通(受到了C2的阻挡)。
4. 游戏双方轮流放置火柴,不可以弃权,也不可以放多根。直到某一方无法继续放置,则该方为负(输的一方)。 游戏开始时可能已经放置了多根火柴。
你的任务是:编写程序,读入初始状态,计算出对自己最有利的放置方法并输出。 如图[1.jpg]的局面表示为: 00-1
-000 0100
即用“0”表示空闲位置,用“1”表示竖直放置,用“-”表示水平放置。 【输入、输出格式要求】
用户先输入整数 n(n<100), 表示接下来将输入 n 种初始局面,每种局面占3行(多个局面间没有空白行)。 程序则输出:每种初始局面情况下计算得出的最佳放置法(行号+列号+放置方式)。 例如:用户输入: 2 0111 -000 -000 1111 ----
0010
则程序可以输出:
00- 211
不难猜出,输出结果的含义为:
对第一个局面,在第0行第0列水平放置 对第二个局面,在第2行第1列垂直放置 注意:
行号、列号都是从0开始计数的。
36
对每种局面可能有多个最佳放置方法(解不唯一),只输出一种即可。 例如,对第一个局面,001 也是正解;最第二个局面,201也是正解。
package Question10_19; import java.util.Scanner; publicclass Question13 {
publicstaticboolean isOk(char[][] state, int i, int j) { }
privatestaticvoid jasdklf(char[][] state) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
if (state[i][j] == '0') {
state[i][j] = '-'; if (isOk(state, i, j)) {
System.out.println(i + \ + j + '-');
37
if (state[i][j] == '-') { }
returntrue;
for (int j2 = j + 1; j2 < 4; j2++) { }
for (int j2 = j - 1; j2 >= 0; j2--) { }
for (int i2 = i + 1; i2 < 3; i2++) { }
for (int i2 = i - 1; i2 >= 0; i2--) { }
if (state[i2][j] == '1') { }
returnfalse; returntrue;
} elseif (state[i2][j] == '-') { if (state[i2][j] == '1') { }
returnfalse; returntrue;
} elseif (state[i2][j] == '-') { if (state[i][j2] == '-') { }
returnfalse; returntrue;
} elseif (state[i][j2] == '1') { if (state[i][j2] == '-') { }
returnfalse; returntrue;
} elseif (state[i][j2] == '1') {
} elseif (state[i][j] == '1') {
}
}
}
}
}
}
return;
state[i][j] = '0'; state[i][j] = '1'; if (isOk(state, i, j)) { }
state[i][j] = '0';
System.out.println(i + \ + j + '1'); return;
publicstaticvoid main(String[] args) { }
Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); scanner.nextLine();
char[][] state = newchar[3][4]; String s;
while ((n--) > 0) { }
for (int i = 0; i < 3; i++) { }
jasdklf(state);
s = scanner.nextLine(); for (int j = 0; j < 4; j++) { }
state[i][j] = s.charAt(j);
方法二:
import java.util.Scanner; import java.util.List; import java.util.ArrayList; public class Demo05 {
static boolean flag = false; // 用来标记是否连通
static boolean flag2 = false; // 用来标记是否没有结果, 如果没有结果输出\空\ // 初始化数组
public static void init(List for(int j=i*3;j lis.get(i)[j%3] = s[j].toCharArray(); } } } // 创建n个数组 初始化,并存入lis 38 public static void input(List String[] s = new String[n*3]; for(int i=0;i init(lis,s,n); // 用输入的数据 初始化每个数组 } // c='1' 检查列上侧是否连通 public static boolean colU(char[][] m,int i,int j,char c){ if(i<0){ flag = true; // 都不连通 return flag; } if(m[i][j]=='0'){ return colU(m,i-1,j,c); }else if(m[i][j]=='1'){ flag = false; // 有一个 '1' 则连通 return flag; }else if(m[i][j]=='-'){ flag = true; // 有一个 '-' 则不连通 return flag; } return flag; } // c='1' 检查列下侧是否连通 public static boolean colD(char[][] m,int i,int j,char c){ if(i>=m.length){ flag = true; // 都不连通 return flag; } if(m[i][j]=='0'){ return colD(m,i+1,j,c); }else if(m[i][j]=='1'){ flag = false; // 有一个 '1' 则连通 return flag; }else if(m[i][j]=='-'){ flag = true; // 有一个 '-' 则不连通 return flag; } return flag; } // c='-' 检查行左侧是否连通 public static boolean rowL(char[][] m,int i,int j,char c){ 39 if(j<0){ flag = true; // 都不连通 return flag; } if(m[i][j]=='0'){ return rowL(m,i,j-1,c); }else if(m[i][j]=='1'){ flag = true; // 有一个 '1' 则不连通 return flag; }else if(m[i][j]=='-'){ flag = false; // 有一个 '-' 则连通 return flag; } return flag; } // c='-' 检查行右侧是否连通 public static boolean rowR(char[][] m,int i,int j,char c){ if(j>=m[i].length){ flag = true; // 都不连通 return flag; } if(m[i][j]=='0'){ return rowR(m,i,j+1,c); }else if(m[i][j]=='1'){ flag = true; // 有一个 '1' 则不连通 return flag; }else if(m[i][j]=='-'){ flag = false; // 有一个 '-' 则连通 return flag; } return flag; } // 当c='1'时 检查是否连通1111111111111111111 public static boolean check1(char[][] m, int i, int j, char c) { if(colU(m,i,j,c)&&colD(m,i,j,c)){ // 是 '1' 时 检查(上下)是否连通 flag = true; }else{ return false; } return flag; } // 当c='-'时 检查是否连通------------------- public static boolean check2(char[][] m, int i, int j, char c) { if(rowL(m,i,j,c)&&rowR(m,i,j,c)){ // 是 '-' 时 检查(左右)是否连通 flag = true; }else{ return false; 40