POJ 1970 The Game (DFS)
题目链接:http://poj.org/problem?id=1970
题意:
有一个19 × 19 的五子棋棋盘,其中“0”代表未放入棋子,“1”代表黑色棋子,”2“代表白色棋子,如果某方的棋子在横,纵,斜这四个方向的连子数(连着的棋子数)恰好为5,那么此方就可以获胜。给你某一刻棋盘上的棋子状态,问你在此刻是哪一方获胜,亦或是平局,平局时仅输出“0”;如果是黑色方获胜,那么输出“1“,白色方获胜输出“2”,并且在第二行输出五连子最左边的棋子的坐标,如果在纵方向五连子,那么输出最上面的那个棋子的坐标。
思路:
首先,对于一个棋子来说,它可以和八个方向的棋子连在一起形成连子,但是这里并用不着对棋子的八个方向进行搜索,因为八个方向实质上可以认为是四个方向,即只需对某个棋子的四个方向进行搜索就OK 了,方向的选择也会影响到程序的复杂性,这里的做法是选择一个当前棋子作为起点(0,0),对这个棋子的”“右上”(-1,1),“右”(0,1),“右下”(1,1),“下”(1,0)这四个方向进行搜索,原因是如果这四个方向能找到五连子,那么作为起点的棋子的坐标即是题目要求的最左边的棋子的坐标,可以降低程序复杂性。方向确定了,搜索的状态就确定了,对于每个棋子有四个状态,所以又需要一个辅助数组来标记棋子的某个状态是否已被搜索过,用一个三维数组visit[i][j][k]代表坐标为(i, j)的棋子其k方向是否已被搜索过,k取值为1~4。然后从左到右、从上到下遍历图,分别从四个方向搜索统计就好了。
由于“右上”方向在搜索中的特殊性,所以这里要解释一些东西。在往“右上”方向搜索的过程中,如果一个棋子的“右上”方向没被搜索过,那么应该尽可能的往这个方向搜索(即使这个方向的其他棋子之前已被搜索过了,这里仍然要进行搜索)。
比如:
0 0 0 0 1...
0 0 0 1 0...
0 0 1 0 0...
0 1 0 0 0...
1 0 0 0 0...
...
首先搜索到的肯定是第一行的”1“,可知连子数为 1个, 但此时并不满足; 再搜索第二行的“1”,此时第一行的1虽然已经搜索过了,但是还需要再搜索一遍,可得连子数为2个; 当搜索到第三行的"1"时,上面的两个"1"仍然要进行搜索统计,可得连子数为3个......底下的两个“1”也是同理,虽然这里可以用记忆化,但是由于搜索树的层数并不深,所以影响不大。
然后当“右上”方向的延伸结果为5时,这里还需要判断“右上”这个方向的反方向(即右下)有没有一样的棋子(否则会出现6连子,不符合题意),之所以要判断“右上”的反方向是否有多余的棋子,是因为位于“右下”的棋子搜索顺序在当前棋子之后,所以“右下”若有相同的棋子,有可能使得本来的5连子形成6连子,但是“右”的反方向“左”、“右下”的反方向“右上”、"下"的反方向“上”,这三个反方向上的棋子的搜索顺序都在当前棋子之前,不用考虑是否会出现这个现象。
代码:
- #include <iostream>
- #include <cmath>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <stack>
- #include <queue>
- #include <algorithm>
- #include <string>
- typedef long long LL;
- using namespace std;
- const int MAXN = ;
- const int stepX[] = {, -, , , };//四个方向
- const int stepY[] = {, , , , };
- int visit[MAXN + ][MAXN + ][];//visit[i][j][k]表示位于[i][j]位置的棋子的k方向是否已被搜索过
- int map[MAXN + ][MAXN + ];//存图
- int cnt;
- void DFS(int x, int y, int id, int dire) {//x,y为坐标,id为1或者2,dire代表方位,即确定方位的进行搜索
- visit[x][y][dire] = ;
- int nex = x + stepX[dire], ney = y + stepY[dire];
- if(map[nex][ney] == id){
- ++cnt;//统计连子数
- DFS(nex, ney, id, dire);
- }
- }
- int main() {
- //freopen("input", "r", stdin);
- int t;
- scanf("%d", &t);
- while(t--) {
- memset(visit, , sizeof(visit));
- memset(map, , sizeof(map));
- cnt = ;
- for(int i = ; i <= ; i++) {
- for(int j = ; j <= ; j++) {
- scanf("%d", &map[i][j]);
- }
- }
- int leftX = -, leftY = -;//五连子最左边棋子的坐标
- int win = ;//获胜的标志
- for(int i = ; i <= ; i++) {
- for(int j = ; j <= ; j++) {
- if(!map[i][j]) continue;
- for(int k = ; k <= ; k++) {
- if(!visit[i][j][k]) {
- cnt = ;
- DFS(i, j, map[i][j], k);
- if(cnt == && map[i - stepX[k]][j - stepY[k]] != map[i][j]) {//判断是否为五连子且考虑反方向是否会造成六连子
- win = map[i][j], leftX = i, leftY = j;
- }
- }
- }
- }
- }
- printf("%d\n", win);
- if(win) printf("%d %d\n", leftX, leftY);
- }
- return ;
- }
POJ 1970 The Game (DFS)的更多相关文章
- POJ 1321 棋盘问题 --- DFS
POJ 1321 题目大意:给定一棋盘,在其棋盘区域放置棋子,需保证每行每列都只有一颗棋子. (注意 .不可放 #可放) 解题思路:利用DFS,从第一行开始依次往下遍历,列是否已经放置棋子用一个数组标 ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- 【POJ - 1970】The Game(dfs)
-->The Game 直接中文 Descriptions: 判断五子棋棋局是否有胜者,有的话输出胜者的棋子类型,并且输出五个棋子中最左上的棋子坐标:没有胜者输出0.棋盘是这样的,如图 Samp ...
- poj 3321 Apple Tree dfs序+线段树
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Description There is an apple tree outsid ...
- 开篇,UVA 755 && POJ 1002 487--3279 (Trie + DFS / sort)
博客第一篇写在11月1号,果然die die die die die alone~ 一道不太难的题,白书里被放到排序这一节,半年前用快排A过一次,但是现在做的时候发现可以用字典树加深搜,于是乐呵呵的开 ...
- poj 1416 Shredding Company( dfs )
我的dfs真的好虚啊……,又是看的别人的博客做的 题目== 题目:http://poj.org/problem?id=1416 题意:给你两个数n,m;n表示最大数,m则是需要切割的数. 切割m,使得 ...
- poj 1129 Channel Allocation ( dfs )
题目:http://poj.org/problem?id=1129 题意:求最小m,使平面图能染成m色,相邻两块不同色由四色定理可知顶点最多需要4种颜色即可.我们于是从1开始试到3即可. #inclu ...
- poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)
http://poj.org/problem?id=3373 Changing Digits Time Limit: 3000MS Memory Limit: 65536K Total Submi ...
- POJ 1699 Best Sequence dfs
题目: http://poj.org/problem?id=1699 无意间A了..超时一次,加了一句 if(len > ans)return; 然后就A了,dfs题,没有太多好说的,代码写的效 ...
随机推荐
- 大步小步算法模板题, poj2417
大步小步模板 (hash稍微有一点麻烦, poj不支持C++11略坑) #include <iostream> #include <vector> #include <c ...
- JS格式化 /Date(xxxxxx)/的日期类型
//用来转换/Date(xxxxxx)/类型的JSON日期为要求的日期格式字符串String.prototype._formatJsonDate = function (format) { var s ...
- BZOJ3242 [Noi2013]快餐店 【环套树 + 单调队列dp】
题目链接 BZOJ3242 题解 题意很清楚,找一点使得最远点最近 如果是一棵树,就是直径中点 现在套上了一个环,我们把环单独拿出来 先求出环上每个点外向树直径更新答案,并同时求出环上每个点外向的最远 ...
- Clevo P950系列拆机
Clevo P950系列(包括神舟精盾T96/T97/T96C/T96E/T97E,炫龙耀9000,铁头人T800同模具机型)拆机 拆机恢复时间:20181203 12:28-14:58 一.普通 ...
- [bzoj 1143]最长反链二分图最大匹配
Dilworth定理:偏序集能划分成的最少的全序集的个数与最大反链的元素个数相等. 证明:http://www.cnblogs.com/itlqs/p/6636222.html 题目让求的是最大反链的 ...
- greendao的基本操作
1.先配置项目的builder.gradle // Top-level build file where you can add configuration options common to all ...
- bzoj2424 [HAOI2010]订货 dp+单调性
[HAOI2010]订货 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1311 Solved: 884[Submit][Status][Discu ...
- Linux 安装编译 FFMPEG
资源准备: ffmpeg-3.4.tar.bz2 yasm-1.3.0.tar.gz 编译安装: 本人二进制包存放在 /opt/moudles中, 解压缩在 /opt/softwares 解包 ffm ...
- 转:Mybatis系列之集合映射
转:Mybatis系列之集合映射 上篇文章我们讲了关联映射,实现了销售与登录用户之间的关联.本文我们接着来讲一讲集合映射,实现销售与客户的多对多关系. 实现销售与客户多对多关系 本文中仍延用<M ...
- C#中file类的应用
现在就其中几个常用的进行介绍: Create:一般使用此重载方法,File.Create (String) ,String是一个路径名,表示文件的完整路径,返回值是一个FileStream实例: Co ...