题解 | #五子棋#

五子棋

http://www.nowcoder.com/questionTerminal/a811535fed784ea492b63622c28c75c5

NowCoder最近爱上了五子棋,现在给你一个棋局,请你帮忙判断其中有没有五子连珠(超过五颗也算)。

输入描述:

输入有多组数据,每组数据为一张20x20的棋盘。

其中黑子用“*”表示,白子用“+”表示,空白位置用“.”表示。

输出描述:

如果棋盘上存在五子连珠(无论哪种颜色的棋子),输入“Yes”,否则输出“No”。

输入解释:

每组20个数据,每个数据由一个20个符号的字符串组成。

思路说明:

遍历每一行每一个列,然后在每一个位置处,如果它是* 或 +,就遍历它横向,纵向, 撇向(右上到左下),捺向(左上,右下)四个方向,每一个方向遍历到与它同符号, 就计数加一。

代码解释:

import java.util.*;
public class Main{
  // 用来统计每一个位置四个方向的* 或 + 数量
    public static int count(String[] arr,int m,int n,char ch){
     // 定义一个三维数组,四个方向,每个方向分相对的两个小方向,每个小方向分X和Y坐标
        int[][][]direction ={
            {{0,-1},{0,1}}, // 左 和 右
            {{-1,0},{1,0}}, // 上 和 下
            {{-1,1},{1,-1}}, // 右上 和 左下
            {{-1,-1},{1,1}} // 左上 和 右下
        };
    // 用来记录四个方向的最大值    
        int result =0;
     // 遍历四个方向   
        for(int i=0;i<4;i++){
       // 每个方向 统计一下* 或 + 的次数 
            int total = 0;
       // 依次统计两个小方向的次数 
            for(int j=0;j<2;j++){
       // 统计两个小方向时,都要从起始位置开始 
                int tx = m;  // 起始位置的X
                int ty = n; // 起始位置的y
           // 从起始位置,沿着一个小方向一直遍历(比如一直遍历左边)  
                for(int k=0;;k++){
               // 如果往左遍历,则 x 加上 横向左边的x 
                    tx = tx+direction[i][j][0];
                     // 如果往左遍历,则 y加上 横向左边的y 
                    ty = ty+direction[i][j][1];
                 // 如果当前遍历位置的X或者Y 没有越界,并且当前位置的符号与起始位置的符号
                    // 相等,则数量加一
                    if(tx >=0 && tx<20 && ty>=0 && ty<20
                       && arr[tx].charAt(ty)== ch){
                        total++;
                     // 反之则退出当前小方向的遍历   
                    }else{
                        break;
                    }
                }
                
            }
            // 拿到四个方向的最大值
            result =Math.max(result,total+1);
        }
        return result;
    }
    
    public static boolean goBang(String[] arr,int m,int n){
     // 遍历每一个位置,如果是* 或者 + ,则遍历四个方向
        for(int i=0;i< m;i++){
            for(int j=0;j<n;j++){
                char ch = arr[i].charAt(j);
                if(ch == '*' || ch=='+'){
                // 任意一个方向返回的* 或+ 次数大于等于5次,就寻找结束
                     if(count(arr,i,j,ch) >= 5)
                    return true;
                }
               
            }
        }
       // 遍历完所有位置的四个方向,依然没有一个符号的次数大于等于五次,就返回false 
        return false;
        
    }
    
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        while(scan.hasNext()){
            String[] arr = new String[20];
            for(int i=0;i<20;i++){
                arr[i] = scan.next();
            }
            System.out.println(goBang(arr,20,20)?"Yes":"No");
        }
    }
}
全部评论

相关推荐

ALEX_BLX:虽然说聊天记录不可信,不过这个趋势确实如此但我觉得也要想到一点就是卷后端的人里真正有“料”的人又有多少,我说的这个料都不是说一定要到大佬那种级别,而是就一个正常的水平。即使是现在也有很多人是跟风转码的,2-3个月速成后端技术栈的人数不胜数,但今时不同往日没可能靠速成进大厂了。这种情况就跟考研一样,你能上考场就已经打败一半的人了
点赞 评论 收藏
分享
小厂面经,也是我的处女面(30min)1.自我介绍2.spring&nbsp;boot的自动装配原理(好多类和接口的单词都忘了全称是啥了,就说了记得的单词,流程应该说对了吧)3.有用过redis吗?主要是用在实现什么功能(说了技术派用redis的zset来实现排行榜)5.有了解过Redisson吗?讲一下对于分布式锁的了解以及在什么场景下应用(说了秒杀场景)6.对mysql有了解吗?包括它的索引优化和创建(把想起来的全说了)7.了解设计模式吗?比如单例模式,为什么要使用单例模式,它的优点是什么(昨天刚看的设计模式)8.工厂模式有了解吗?主要的使用场景是?(也是昨天刚看的)9.场景题:有7个服务器,需要在早上十点定时的向数据库中的用户表中的用户发短信,如果做到发送的消息不重复,且如果发送失败了需要知道是到哪个用户失败了,这样下次就直接从这个用户开始(我答了用spring&nbsp;task来实现定时,用分布式锁来保证只有一份服务器可以发送消息,用消息队列来存储消息,然后用消息确认机制来保证错误信息的记录,以及在数据库或者业务层面完成消息消费的幂等性)10.场景题:如果在系统启动的时间就将数据库的所有用户相关的信息都读到一个hashmap中(这个没啥思路,没答好)27届的投了一个星期终于有一个面试了,大部分公司都只招26的
inari233:已oc,拒了
查看9道真题和解析
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务