BUAA数据结构第二次作业题解——五子棋危险判断

【问题描述】

已知两人分别执白棋和黑棋在一个围棋棋盘上下五子棋,若同一颜色的棋子在同一条横行、纵行或斜线上连成5个棋子,则执该颜色棋子的人获胜。编写程序读入某一时刻下棋的状态,并判断是否有人即将获胜,即:同一颜色的棋子在同一条横行、纵列或斜线上连成4个棋子,且该4个棋子的两端至少有一端为空位置。
输入的棋盘大小是19×19,用数字0表示空位置(即没有棋子),用数字1表示该位置下了一白色棋子,用数字2表示该位置下了一黑色棋子。假设同一颜色的棋子在同一条横行、纵列或斜线上连成的棋子个数不会超过4个,并且最多有一人连成线的棋子个数为4。

【输入形式】

从控制台输入用来表示棋盘状态的数字0、1或2;每行输入19个数字,各数字之间以一个空格分隔,每行最后一个数字后没有空格;共输入19行表示棋盘状态的数字。

【输出形式】

若有人即将获胜,则先输出即将获胜人的棋子颜色(1表示白色棋子,2表示黑色棋子),然后输出英文冒号:,最后输出连成4个棋子连线的起始位置(棋盘横行自上往下、纵列自左往右从1开始计数,横行最小的棋子在棋盘上的横行数和纵列数作为连线的起始位置,若在同一行上,则纵列数最小的棋子位置作为起始位置,两数字之间以一个英文逗号,作为分隔符)。
若没有人获胜,则输出英文字符串:No。
无论输出什么结果,最后都要有回车换行符。

【输入样例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 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 2 0 1 1 2 0 0 0 0 0 0 0
0 0 0 0 0 2 1 1 1 1 2 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 2 1 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 0 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 1 0 0 2 0 0 0 0 0 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 0 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

【输出样例1】

1:9,8

【输入样例2】

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 1 2 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 0 0 0 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

【输出样例2】

No


【样例说明】

在输入的样例1中,执白棋(数字1表示)的人即将获胜,连成4个棋子且有一端为空的起始位置在第9行第8列,所以输出1:9,8。
在输入的样例2中,还没有同一颜色的棋子连成4个,所以无人即将获胜,直接输出No。

【评分标准】

该题要求判断五子棋的棋盘状态,提交程序文件名为chess.c

【思路】
通过对几种危险情况分类进行判断来实现目标
要注意危险情况中的向右上和向左下其实是一种情况,不妨从左从上开始遍历,都按照向右方向进行判断

#include <stdio.h>
int a[20][20];



int main() {
	int c = 0;
	for (int i = 1; i <= 19; i++) {
		for (int m = 1; m <= 19; m++) {
			scanf("%d", &a[i][m]);
		}
	}//输入
	 
	for (int i = 1; i <= 19; i++) {
		for (int x = 1; x <= 15; x++) {
			if (((a[i][x] == 1) || (a[i][x] == 0)) && (a[i][x + 1] == 1) && (a[i][x + 2] == 1) && (a[i][x + 3] == 1) && ((a[i][x + 4] == 1) || (a[i][x + 4] == 0))) {
				if (a[i][x] == 1)
					printf("1:%d,%d\n", i, x);
				else if (a[i][x] == 0 && a[i][x + 4] == 1)
					printf("1:%d,%d\n", i, x + 1);
				else if (a[i][x] == 0 && a[i][x + 4] == 0)
					break;
				c++;
				return 0;
			}//横1 

			else if (((a[i][x] == 2) || (a[i][x] == 0)) && (a[i][x + 1] == 2) && (a[i][x + 2] == 2) && (a[i][x + 3] == 2) && ((a[i][x + 4] == 2) || (a[i][x + 4] == 0)) ) {
				if (a[i][x] == 2)
					printf("2:%d,%d\n", i, x);
				else if (a[i][x] == 0 && a[i][x + 4] == 2)
					printf("2:%d,%d\n", i, x + 1);
				else if (a[i][x] == 0 && a[i][x + 4] == 0)
					break;

				c++;
				return 0;
			}//横2 
		}
	}
	for (int i = 1; i <= 19; i++) {
		for (int x = 1; x <= 15; x++) {
			if (((a[x][i] == 1) || (a[x][i] == 0)) && (a[x + 1][i] == 1) && (a[x + 2][i] == 1) && (a[x + 3][i] == 1) && ((a[x + 4][i] == 1) || (a[x + 4][i] == 0))) {
				if (a[x][i] == 1)
					printf("1:%d,%d\n", x, i);
				else if (a[x][i] == 0 && a[x + 4][i] == 1)
					printf("1:%d,%d\n", x + 1, i);
				else if (a[x][i] == 0 && a[x + 4][i] == 0)
					break;

				c++;

				return 0;
			}//竖1 


			else	if (((a[x][i] == 2) || (a[x][i] == 0)) && (a[x + 1][i] == 2) && (a[x + 2][i] == 2) && (a[x + 3][i] == 2) && ((a[x + 4][i] == 2) || (a[x + 4][i] == 0))) {
				if (a[x][i] == 2)
					printf("2:%d,%d\n", x, i);
				else if (a[x][i] == 0 && a[x + 4][i] == 2)
					printf("2:%d,%d\n", x + 1, i);
				else if (a[x][i] == 0 && a[x + 4][i] == 0)
					break;

				c++;
				return 0;
			}//竖2 
		}
	}
	for (int x = 1; x <= 15; x++) {
		for (int i = 1; i <= 15; i++) {
			if (((a[x][i] == 1) || (a[x][i] == 0)) && (a[x + 1][i + 1] == 1) && (a[x + 2][i + 2] == 1) && (a[x + 3][i + 3] == 1) && ((a[x + 4][i + 4] == 1) || (a[x + 4][i + 4] == 0))) {
				if (a[x][i] == 1)
					printf("1:%d,%d\n", x, i);
				else if (a[x][i] == 0 && a[x + 4][i + 4] == 1)
					printf("1:%d,%d\n", x + 1, i + 1);
				else if (a[x][i] == 0 && a[x + 4][i + 4] == 0)
					break;
				c++;
				return 0;
			}//右下斜1 

			else if (((a[x][i] == 2) || (a[x][i] == 0)) && (a[x + 1][i + 1] == 2) && (a[x + 2][i + 2] == 2) && (a[x + 3][i + 3] == 2) && ((a[x + 4][i + 4] == 2) || (a[x + 4][i + 4] == 0))) {
				if (a[x][i] == 2)
					printf("2:%d,%d\n", x, i);
				else if (a[x][i] == 0 && a[x + 4][i + 4] == 2)
					printf("2:%d,%d\n", x + 1, i + 1);
				else if (a[x][i] == 0 && a[x + 4][i + 4] == 0)
					break;
				c++;
				return 0;

			}//右下斜2 

		}
	}
	for (int x = 5; x <= 19; x++) {
		for (int i = 1; i <= 15; i++) {
			if (((a[x][i] == 1) || (a[x][i] == 0)) && (a[x - 1][i + 1] == 1) && (a[x - 2][i + 2] == 1) && (a[x - 3][i + 3] == 1) && ((a[x - 4][i + 4] == 1) || (a[x - 4][i + 4] == 0))) {
				if (a[x][i] == 1)
					printf("1:%d,%d\n", x - 3, i + 3);
				else if (a[x][i] == 0 && a[x + 4][i + 4] == 1)
					printf("1:%d,%d\n", x - 4, i + 4);
				else if (a[x][i] == 0 && a[x + 4][i + 4] == 0)
					break;
				c++;
				return 0;//右上斜1 
			} else if (((a[x][i] == 2) || (a[x][i] == 0)) && (a[x - 1][i + 1] == 2) && (a[x - 2][i + 2] == 2) && (a[x - 3][i + 3] == 2) && ((a[x - 4][i + 4] == 2) || (a[x - 4][i + 4] == 0))) {
				if (a[x][i] == 2)
					printf("2:%d,%d\n", x - 3, i + 3);
				else if (a[x][i] == 0 && a[x - 4][i + 4] == 2)
					printf("2:%d,%d\n", x - 4, i + 4);
				else if (a[x][i] == 0 && a[x - 4][i + 4] == 0)
					break;
				c++;
				return 0;
			}//右上斜2 
		}
	}
	if (c == 0) {
		printf("No\n");
	}

	return 0;



}

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值