题目翻译:
一个由19位的19人组成的玩家,由两名玩家组成。一个玩家使用黑石头,另一个玩家使用白石。游戏开始于一个空白的棋盘,两个玩家交替放置黑石头和白石。黑色总是先走。板上有19条水平线和19条垂直线,石头放在线路的交点处。
水平线从上到下标记为1,2,...,19,垂直线从左到右标记为1,2,...,19。
这个游戏的目标是沿着水平,垂直或对角线连续地放置相同颜色的五个石头。所以黑色在上图中赢了。但是,如果超过五颗相同颜色的石头连续投放,玩家就不会赢得比赛。
给定一个游戏的配置,写一个程序,以确定白色是赢得还是黑色赢了,还没有人赢了。黑色和白色都不会同时获胜的输入数据。也不会有白色或黑色在多个地方获胜的输入数据。
输入
输入的第一行包含单个整数t(1 <= t <= 11),测试用例数,后跟每个测试用例的输入数据。每个测试用例由19行组成,每行有19个数字。黑色石头由1表示,白色石头由2表示,0表示无石头。
输出
每个测试用例应该有一行或两行。在测试用例输出的第一行中,如果黑色获胜,则应打印1,如果为白色,则应打印2,如果没有人赢,则应打印为0。如果黑色或白色获胜,请在第二行打印五个连续石块中最左边石头的水平线数和垂直线数。 (如果连续五个石头垂直放置,请选择最上面的石头。)
Sample Input
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Sample Output
1 3 2
代码如下:
/*
解释1,2,3层判断:
如果在“if(m==5)”判断没有通遍历会绕过该判断接着下一次遍历,
直到i=19;而这种情况不是黑子白子都出现五子就是都没赢,
所以3进行了判断(if(i<19)),而1和2是为了跳出到3;
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
//输入数据,数组初始化;
int grid[21][21]={0};
//四个方向的坐标:dir[0][0]=0,dir[0][1]=1,dir[1][0]=1,dir[1][1]=0...;
int dir[4][2]={{0,1},{1,0},{1,1},{-1,1}};
int main(){
int t,m,i,j,k,x,y;
m=0;
scanf("%d",&t);
while(t--){
//输入数据;
for(i=1;i<=19;++i){
for(j=1;j<=19;j++)
scanf("%d",&grid[i][j]);
}
//对输入数据进行遍历;
for(i=1;i<=19;++i){
for(j=1;j<=19;++j){
//如果该位置为零跳过;
if(grid[i][j]==0) continue;
for(k=0;k<=3;++k){
//判断该位置是否与左,上,左上,左下相等,以此来防止出现六子相连的情况;
x=i-dir[k][0];//对应值:0,1,1,-1;
y=j-dir[k][1];//对应值:1,0,1,1;
//如果出现相等的情况就跳过,因为在该遍历方法下可能会出现六子相连的情况;
if(grid[i][j]==grid[x][y]) continue;
//如果在与该方向相反的方向上没有与该位置相等,则遍历该方向上的五个子;
else{
//将x和y赋值为改为值的坐标,作为方向的起点;
x=i,y=j;
//依次判断该方向上的五个点是否和起点相等;
for(m=1;m<=4;++m){
x+=dir[k][0];
y+=dir[k][1];
//如果不相等就跳出,判断下一个方向;
if(grid[i][j]!=grid[x][y]) break;
}
//判断该方向上的地六个子是否也和起点相等;
//必须判断m是否等于5,因为此次循环的起始点不一定为该方向上的最顶端点;
if(m==5){
x+=dir[k][0];y+=dir[k][1];
//如果相等接着判断下一个方向,说明出现了六子相连的情况;
if(grid[i][j]==grid[x][y]) continue;
//如果不相等,说明没有六子相连,跳出该位置的四个方向的判断;
else break;
}
}
}
//1,方向层判断;
if(k<=3) break;
}
//2,列层判断;
if(j<=19) break;
}
//3.行层判断;
if(i<19){
cout<<grid[i][j]<<endl;
cout<<i<<" "<<j<<endl;
}
else cout<<"0"<<endl;
}
return 0;
}