题目链接: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)的更多相关文章

  1. POJ 1321 棋盘问题 --- DFS

    POJ 1321 题目大意:给定一棋盘,在其棋盘区域放置棋子,需保证每行每列都只有一颗棋子. (注意 .不可放 #可放) 解题思路:利用DFS,从第一行开始依次往下遍历,列是否已经放置棋子用一个数组标 ...

  2. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  3. 【POJ - 1970】The Game(dfs)

    -->The Game 直接中文 Descriptions: 判断五子棋棋局是否有胜者,有的话输出胜者的棋子类型,并且输出五个棋子中最左上的棋子坐标:没有胜者输出0.棋盘是这样的,如图 Samp ...

  4. poj 3321 Apple Tree dfs序+线段树

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K       Description There is an apple tree outsid ...

  5. 开篇,UVA 755 && POJ 1002 487--3279 (Trie + DFS / sort)

    博客第一篇写在11月1号,果然die die die die die alone~ 一道不太难的题,白书里被放到排序这一节,半年前用快排A过一次,但是现在做的时候发现可以用字典树加深搜,于是乐呵呵的开 ...

  6. poj 1416 Shredding Company( dfs )

    我的dfs真的好虚啊……,又是看的别人的博客做的 题目== 题目:http://poj.org/problem?id=1416 题意:给你两个数n,m;n表示最大数,m则是需要切割的数. 切割m,使得 ...

  7. poj 1129 Channel Allocation ( dfs )

    题目:http://poj.org/problem?id=1129 题意:求最小m,使平面图能染成m色,相邻两块不同色由四色定理可知顶点最多需要4种颜色即可.我们于是从1开始试到3即可. #inclu ...

  8. poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)

    http://poj.org/problem?id=3373 Changing Digits Time Limit: 3000MS   Memory Limit: 65536K Total Submi ...

  9. POJ 1699 Best Sequence dfs

    题目: http://poj.org/problem?id=1699 无意间A了..超时一次,加了一句 if(len > ans)return; 然后就A了,dfs题,没有太多好说的,代码写的效 ...

随机推荐

  1. JDK的弃儿:Vector、Stack、Hashtable、Enumeration

    随着JDK的发展,一些设计缺陷或者性能不足的类库难免会被淘汰,最常见的就是Vector.Stack.HashTable和Enumeration了. Vector(@since 1.0) 首先看看Vec ...

  2. day10_plus

    刚才发奖哈哈哈 想不到被惨虐的我还能混个牌子哈哈哈好开心

  3. 什么是node.js的事件驱动编程

    Node.js现在非常活跃,相关生态社区已经超过Lua(基本上比较知名的功能都有nodejs模块实现).但是我们为何要使用Node.Js?相比传统的webserver服务模式,nodejs有什么优点优 ...

  4. ng4转义html

    https://stackoverflow.com/questions/31548311/angular-html-binding <div [innerHTML]="content& ...

  5. rsync 同步

    1./usr/bin/rsync -vzrtopg --progress  --include "weibo-service-server" --exclude "/*& ...

  6. 设备VMnet0上的网络桥接当前未在运行解决办法

    问题: 今天把自己的VM从C盘挪到了D盘,然后再open所有VM都会显示网卡无法桥接了 “vmware 没有未桥接的主机网络适配器” 解决办法: 1.关闭所有VM 2.打开 编辑-虚拟网络编辑器,会发 ...

  7. HTML5之SVG详解(一):基本概括

    转载自:http://www.cnblogs.com/hupeng/archive/2012/12/21/2828456.html 1.背景 SVG是Scalable Vector Graphics的 ...

  8. 一些常用的css片段

    1. 单行文字溢出时省略号 .test{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } 2. 多行文字溢出时省略号 .t ...

  9. sql数据库的链接方式

    今天看见了一个数据库的链接方法,给转载了,记得我刚刚学DAO的时候老是要记载这些东西,所以就上博客园上面看了看,就转过来了... MySQL: String Driver="com.mysq ...

  10. hive的体系架构及安装

    1,什么是Hive? Hive是能够用类SQL的方式操作HDFS里面数据一个数据仓库的框架,这个类SQL我们称之为HQL(Hive Query Language) 2,什么是数据仓库? 存放数据的地方 ...