Alice and Bob play 5-in-a-row game. They have a playing field of size 10 × 10. In turns they put either crosses or noughts, one at a time. Alice puts crosses and Bob puts noughts.
In current match they have made some turns and now it's Alice's turn. She wonders if she can put cross in such empty cell that she wins immediately.
Alice wins if some crosses in the field form line of length not smaller than 5. This line can be horizontal, vertical and diagonal.
You are given matrix 10 × 10 (10 lines of 10 characters each) with capital Latin letters 'X' being a cross, letters 'O' being a nought and '.' being an empty cell. The number of 'X' cells is equal to the number of 'O' cells and there is at least one of each type. There is at least one empty cell.
It is guaranteed that in the current arrangement nobody has still won.
Print 'YES' if it's possible for Alice to win in one turn by putting cross in some empty cell. Otherwise print 'NO'.
XX.XX.....
.....OOOO.
..........
..........
..........
..........
..........
..........
..........
..........
YES
XXOXX.....
OO.O......
..........
..........
..........
..........
..........
..........
..........
..........
NO
题意:
多组输入,五子棋的规则。给一个10*10的棋盘,棋盘内有两种棋子“X”和“O”,现在要再加入一个棋子“X”,使得棋子“X”可以按照五子棋的规则连成五个或五个以上。如果加入一个可以连成的话输出“YES”,不能的话输出“NO”。
解题思路:
本来需要用搜索写,但因为可能性少,并且需要搜的步数也少,所以直接暴力,模拟一下可能的情况就可以。从棋盘左上角开始遍历棋盘,找到“.”的话就假定把棋子放在这里,然后简单搜索一下这颗棋子周围八个方向的棋子情况。说是八个方向,其实就是四种情况,横着连,竖着连,两个对角线连。每种情况用两个for循环来搜索,一个循环搜索一个方向,比如一个往左搜,一个往右搜,在不超出棋盘范围的前提下,如果相邻的是“X”,棋子数加1,不是的话直接跳出循环。两个for循环判断完,如果棋子数大于等于4的话说明可以连,标记一下后返回调用的地方。如果不是大于等于四,将棋子数清零,继续判断下一组情况。
注意:
用gets输入时,每组数据后要加一个getchar()来吸收回车,不然回车会被gets吸收。在搜索对角线的情况时,横坐标和纵坐标不是同等加减一的,比如往右上搜,横坐标-1,纵坐标是+1,需要独立变换。满足条件的棋子个数应该是大于等于4,不一定是恰好五个。
AC代码:
#include<stdio.h> #include<string.h> char mp[15][15]; int flag, sum; void dfs( int x, int y ) { for( int i=x,j=y-1; j>=0; j-- )//向左 { if(mp[i][j] != 'X') break; else sum++; } for( int i=x,j=y+1; j<10; j++ )//向右 { if(mp[i][j] != 'X') break; else sum++; } if( sum >= 4 ) { flag = 1; return ; } else sum = 0; for( int i=x-1,j=y; i>=0; i-- )//向上 { if(mp[i][j] != 'X') break; else sum++; } for( int i=x+1,j=y; i<10; i++ )//向下 { if(mp[i][j] != 'X') break; else sum++; } if( sum >= 4 ) { flag = 1; return ; } else sum = 0; for( int i=x,j=y,t=1; t<=4; t++ )//向左上 { if( i-t<0 || j-t<0 || mp[i-t][j-t] != 'X') break; else sum++; } for( int i=x,j=y,t=1; t<=4; t++ )//向右下 { if( i+t>=10 || j+t>=10 || mp[i+t][j+t] != 'X') break; else sum++; } if( sum >= 4 ) { flag = 1; return ; } else sum = 0; for( int i=x,j=y,t=1; t<=4; t++ )//向右上,注意横纵坐标不同等变化 { if( i-t<0 || j+t>=10 || mp[i-t][j+t] != 'X') break; else sum++; } for( int i=x,j=y,t=1; t<=4; t++ )//向左下,注意横纵坐标不同等变化 { if( i+t>=10 || j-t<0 || mp[i+t][j-t] != 'X') break; else sum++; } if( sum >= 4 ) { flag = 1; return ; } else sum = 0; } int main() { while( gets(mp[0]) ) { for( int i = 1; i < 10; i++ ) scanf("%s",mp[i]); flag = 0; for( int i = 0; i < 10; i++ ) { for( int j = 0; j < 10; j++ ) { if( mp[i][j] == '.' ) { sum = 0; dfs(i,j); } if( flag ) break; } if( flag ) break; } if( flag ) printf("YES\n"); else printf("NO\n"); getchar(); //用gets输入时结尾记得加getchar() } //不然回车会被gets吸收 return 0; }