题目描述
解题思路
使用一个3维数组input[][3][3],保存输入的棋局的状态。再使用一个一维数组result[],保存每个棋局的胜负情况,用数字表示胜负。3表示o胜,12表示x胜,0表示棋盘下满平局,-1表示不存在的棋盘状态。
对于每一个棋局,输入3*3的状态之后,就对其胜负情况进行判定。分别判断每一行,每一列,对角线及反对角线的状态,并将最终判定结果值存入到result数组中。
实现代码
#include<iostream>
#define SBOUNDARY 2000
#define BOARDSIZE 3
using namespace std;
int status[8]; // 记录3行3列及两个对角线的和的情况
int input[SBOUNDARY][3][3]; // 每一个输入都单独进行处理,且后续没有对棋盘进行遍历,因此只需要使用一个[3][3]矩阵即可
int result[SBOUNDARY];
int main(){
char c;
int S = 0;
int x_count = 0;
int o_count = 0;
cin>>S;
for(int s=0;s<S;s++){
x_count = 0;
o_count = 0;
for(int i=0;i<8;i++){
status[i] = 0;
}
// 输入棋局
for(int i=0;i<BOARDSIZE;i++){
for(int j=0;j<BOARDSIZE;j++){
cin>>c;
// 对输入进行统计,以判定棋盘状态
if(c == 'X'){
input[s][i][j] = 1;
x_count++;
}else if(c == 'O'){
input[s][i][j] = 4;
o_count++;
}else if(c == '_'){
input[s][i][j] = 0;
}
if(i==0){ // 第一行
status[0]+=input[s][i][j];
}else if(i==1){ // 第二行
status[1]+=input[s][i][j];
}else if(i==2){ // 第三行
status[2]+=input[s][i][j];
}
if(j==0){ // 第一列
status[3]+=input[s][i][j];
}else if(j==1){
status[4]+=input[s][i][j];
}else if(j==2){
status[5]+=input[s][i][j];
}
if(i == j){ // 对角线
status[6]+=input[s][i][j];
}
if(i+j == 2){ // 反对角线
status[7]+=input[s][i][j];
}
}
}
// 对当前输入的棋局进行判断
if(x_count < o_count ){ // 非法状态
result[s] = -1;
}else{
int i=0;
for(;i<8;i++){
if(status[i] == 3){
result[s] = 3; // x胜;使用3标记为x获胜--代表存在3个连续的1
break;
}else if(status[i] == 12){
result[s] = 12; // o胜;使用12标记o获胜--代表存在3个连续的4
break;
}else if(status[i] == 2 && x_count == o_count){ // 出现两个连续的x且下一步该x走
result[s] = 4; // next x胜
break;
}else if(status[i] == 8 && x_count == (o_count+1)){ // 出现两个连续的o且下一步该o走
result[s] = 13; // next o胜
break;
}
}
if(i == 8 && (x_count+o_count) == 9){ // 如果未出现上述胜负情况,那么判断是否平局
result[s] = 1; // 棋盘下满,平局;平局不能将值设为result[]的初始默认值0
}
}
}
// 根据结果数组中数字值输出各个棋局的胜负情况
for(int i=0;i<S;i++){
if(result[i] == -1){
cout<<"Invalid"<<endl;
}else if(result[i] == 3){
cout<<"X win"<<endl;
}else if(result[i] == 12){
cout<<"O win"<<endl;
}else if(result[i] == 4 || result[i] == 13){
cout<<"Next win"<<endl;
}else if(result[i] == 1){
cout<<"Draw"<<endl;
}else {
cout<<"Next cannot win"<<endl;
}
}
return 0;
}
测试用例及输出
输出结果:
第一个例子,因为X先下,所以该局面不可能出现
第二个例子,为结束局面,X取胜
第三个例子,全部格子下完,双方均无法取胜,平局
第四个例子,局面未分胜负,下一个下的是X,可以取胜
第五个例子,局面未分胜负,下一个下的是O,无论下到哪一个格子均无法取胜
由于题目只是一个3*3的简单棋盘,所以没有对其进行扩展,但是思路都是一样的。
另外,还有就是对于棋盘的输入状态也是不必要存储的,只需要一个3*3数组即可,不需要一个3维数组。