题目链接:P1838 三子棋I - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目描述
小a和uim喜欢互相切磋三子棋。三子棋大家都玩过是吗?就是在九宫格里面OOXX(别想歪了),谁连成3个就赢了。
由于小a比较愚蠢,uim总是让他先。
我们用9个数字表示棋盘位置:
123
456
789
所有的棋谱都是已经结束的棋局,要么一方获胜,要么平局。
今天,他们下了一下午的棋,小a为了提高技术,录下了很多棋谱。他想知道,一盘棋结束时,到底是谁赢。
输入格式
一行,一串数字,表示落子的地点。小a总是先下。
输出格式
一行,如果小a赢,输出“xiaoa wins.”。如果uim赢,输出“uim wins.”。如果平局,输出“drew.”。
样例 #1
样例输入 #1
5237649
样例输出 #1
xiaoa wins.
样例 #2
样例输入 #2
539128647
样例输出 #2
drew.
解题思路
用 3×3 二维数组模拟棋盘,为了能够更加方便快捷地求出数字对应的数组横纵坐标,因此将棋盘中数字编号为0~8,数组横纵下标为0~2。
假设数字为x,则 x / 3 就是数字x在数组当中所对应的横坐标,x % 3 就是数字x在数组当中所对应的纵坐标。
数组下标及棋盘数字对应位置如下图所示:
AC code:
#include<iostream>
#include<algorithm>
using namespace std;
int a[3][3];
bool check(int x , int y , int c , int m)
{
// 判断行或列
bool flag = 1;
for(int i = 0 ; i < 3 ; i ++) // 列
if(a[i][y] != m)
flag = 0;
if(flag == 1)
return true;
flag = 1;
for(int i = 0 ; i < 3 ; i ++) // 行
if(a[x][i] != m)
flag = 0;
if(flag == 1)
return true;
// 判断对角线
if(c == 0 || c == 2 || c == 4 || c == 6 || c == 8)
{
// 主对角线
flag = 1;
for(int i = 0 ; i < 3 ; i ++)
for(int j = 0 ; j < 3 ; j ++)
if(i == j && a[i][j] != m)
flag = 0;
if(flag == 1)
return true;
// 次对角线
flag = 1;
for(int i = 0 ; i < 3 ; i ++)
for(int j = 2 ; j >= 0 ; j --)
if(i + j == 2 && a[i][j] != m)
flag = 0;
if(flag == 1)
return true;
}
return false;
}
int main()
{
string s;
cin>>s;
for(int i = 0 , x ; i < 9 ; i ++)
{
x = s[i] - '0' - 1;
if(i % 2 == 0)
{
a[x / 3][x % 3] = 1; // xiaoa下
if(check(x / 3 , x % 3 , x , 1))
{
cout<<"xiaoa wins.";
return 0;
}
}
else
{
a[x / 3][x % 3] = 2; // uim下
if(check(x / 3 , x % 3 , x , 2))
{
cout<<"uim wins.";
return 0;
}
}
}
cout<<"drew.";
return 0;
}