每日刷题记录(十三)

目录

  • 第一题:走方格的方案数
    • 解题思路:
    • 代码实现:
  • 第二题:井字棋
    • 解题思路:
    • 代码实现:
  • 第三题:密码强度等级
    • 解题思路:
    • 代码实现:
  • 第四题:最近公共祖先
    • 解题思路:
    • 代码实现:
  • 第五题:求最大连续bit数
    • 解题思路:
    • 代码实现:

第一题:走方格的方案数

描述
请计算n*m的棋盘格子(n为横向的格子数,m为竖向的格子数)从棋盘左上角出发沿着边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。
注:沿棋盘格之间的边缘线行走
数据范围: 1≤n,m≤8

输入描述:
输入两个正整数n和m,用空格隔开。(1≤n,m≤8)

输出描述:
输出一行结果

示例1

输入: 2 2
输出: 6

解题思路:

  1. 如果n或者m为1,则只有一行或者一列,从左上角走到右下角的路径数为n + m
  2. 如果n,m都大于1,那么走到[n][m]格子的右下角只有向下或者向右两条路径,所以走到[n][m]格子的右下角的数量为[n-1][m] + [n][m - 1],可以通过递归实现,情况1为递归的终止条件

代码实现:

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) { 
            int n = in.nextInt();
            int m = in.nextInt();
            System.out.println(fun(n,m));
        }
    }
    public static int fun(int n,int m) {
        if((n == 1 && m >= 1) || (m == 1 && n >= 1)) {
            return m+n;
        }
        return fun(n-1,m)+fun(n,m-1);
    }

第二题:井字棋

描述
给定一个二维数组board,代表棋盘,其中元素为1的代表是当前玩家的棋子,0表示没有棋子,-1代表是对方玩家的棋子。当一方棋子在横竖斜方向上有连成排的及获胜(及井字棋规则),返回当前玩家是否胜出。

测试样例:

[[1,0,1],[1,-1,-1],[1,-1,0]]
返回:true

解题思路:

  1. 判断每一行获胜的情况
  2. 判断每一列获胜的情况
  3. 判断主对角线获胜的情况
  4. 判断副对角线获胜的情况

代码实现:

public class Board {
    public boolean checkWon(int[][] board) {
        int size = board.length;
        int sum = 0;
        int i = 0;
        int j = 0;

        //判断每一行是否元素和是否为size
        for(i = 0;i < size;i++) {
            for(j = 0;j < size;j++) {
                sum += board[i][j];
            }
            if(sum == size) {
                return true;
            }
            sum = 0;
        }
        //判断每一列是否元素和是否为size
        for(j = 0;j < size;j++) {
            sum = 0;
            for(i = 0;i < size;i++) {
                sum += board[i][j];
            }
            if(sum == size) {
                return true;
            }
        }
        //判断主对角线是否元素和是否为size
        sum = 0;
        for(i = 0;i < size;i++) {
            sum += board[i][i];
        }
        if(sum == size) {
            return true;
        }
        //判断副对角线是否元素和是否为size
        sum = 0;
        for(i = 0;i < size;i++) {
            sum += board[i][size-i-1];
        }
        if(sum == size) {
            return true;
        }
        return false;
    }
}

第三题:密码强度等级

描述
密码按如下规则进行计分,并根据不同的得分为密码进行安全等级划分。

一、密码长度:
5 分: 小于等于4 个字符
10 分: 5 到7 字符
25 分: 大于等于8 个字符
二、字母:
0 分: 没有字母
10 分: 密码里的字母全都是小(大)写字母
20 分: 密码里的字母符合”大小写混合“
三、数字:
0 分: 没有数字
10 分: 1 个数字
20 分: 大于1 个数字
四、符号:
0 分: 没有符号
10 分: 1 个符号
25 分: 大于1 个符号
五、奖励(只能选符合最多的那一种奖励):
2 分: 字母和数字
3 分: 字母、数字和符号
5 分: 大小写字母、数字和符号

最后的评分标准:
>=90: 非常安全
>= 80: 安全(Secure)
>= 70: 非常强
>= 60: 强(Strong)
>= 50: 一般(Average)
>= 25: 弱(Weak)
>= 0: 非常弱(Very_Weak)

对应输出为:
VERY_SECURE
SECURE
VERY_STRONG
STRONG
AVERAGE
WEAK
VERY_WEAK

请根据输入的密码字符串,进行安全评定。
注:
字母:a-z, A-Z
数字:0-9
符号包含如下: (ASCII码表可以在UltraEdit的菜单view->ASCII Table查看)
!"#$%&'()*+,-./ (ASCII码:0x21~0x2F)
:;<=>?@ (ASCII码:0x3A~0x40)
[]^_` (ASCII码:0x5B~0x60)
{|}~ (ASCII码:0x7B~0x7E)

提示:

  • 1 <= 字符串的长度<= 300

输入描述:
输入一个string的密码

输出描述:
输出密码等级

示例1

输入: 38$@NoNoN
输出: VERY_SECURE
说明:样例的密码长度大于等于8个字符,得25分;大小写字母都有所以得20分;有两个数字,所以得20分;包含大于1符号,所以得25分;由于该密码包含大小写字母、数字和符号,所以奖励部分得5分,经统计得该密码的密码强度为25+20+20+25+5=95分。

示例2

输入: Jl)M:+
输出: AVERAGE
说明: 示例2的密码强度为10+20+0+25+0=55分。

解题思路:

对长度,字母,数字,符号单独判断,最后把所有的单项值根据题目要求相加,输出对应的安全级别

代码实现:

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String str = in .nextLine();
            int sum1 = getLen(str);
            int sum2 = getChar(str);
            int sum3 = getNum(str);
            int sum4 = getSym(str);
            int sum = 0;
            if (sum2 == 20 && sum3 >= 10 && sum4 >= 10) {
                sum = sum1 + sum2 + sum3 + sum4 + 5;
            } else if (sum2 == 10 && sum3 >= 10 && sum4 >= 10) {
                sum = sum1 + sum2 + sum3 + sum4 + 3;
            } else if (sum2 == 10 && sum3 >= 10 && sum4 == 0) {
                sum = sum1 + sum2 + sum3 + sum4 + 2;
            } else {
                sum = sum1 + sum2 + sum3 + sum4;
            }

            if (sum >= 90) {
                System.out.println("VERY_SECURE");
            } else if (sum >= 80) {
                System.out.println("SECURE");
            } else if (sum >= 70) {
                System.out.println("VERY_STRONG");
            } else if (sum >= 60) {
                System.out.println("STRONG");
            } else if (sum >= 50) {
                System.out.println("AVERAGE");
            } else if (sum >= 25) {
                System.out.println("WEAK");
            } else {
                System.out.println("VERY_WEAK");
            }
        }
    }
    public static int getLen(String str) {
        int len = str.length();
        if (len >= 8) {
            return 25;
        } else if (len <= 4) {
            return 5;
        } else if (len > 4 && len < 8) {
            return 10;
        }
        return 0;
    }
    public static int getChar(String str) {
        int big = 0;
        int small = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) >= 65 && str.charAt(i) <= 90) {
                big++;
            } else if (str.charAt(i) >= 97 && str.charAt(i) <= 122) {
                small++;
            }
        }
        if (small > 0 && big > 0) {
            return 20;
        } else if (small > 0 || big > 0) {
            return 10;
        }
        return 0;
    }
    public static int getNum(String str) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) - '0' >= 0 && str.charAt(i) - '0' <= 9) {
                count++;
            }
        }
        if (count > 1) {
            return 20;
        } else if (count == 1) {
            return 10;
        }
        return 0;
    }
    public static int getSym(String str) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            if (!(str.charAt(i) >= 65 && str.charAt(i) <= 90)
                    && !(str.charAt(i) >= 97 && str.charAt(i) <= 122)
                    && !(str.charAt(i) - '0' >= 0 && str.charAt(i) - '0' <= 9)) {
                count++;
            }
        }
        if (count > 1) {
            return 25;
        } else if (count == 1) {
            return 10;
        }
        return 0;
    }
}

第四题:最近公共祖先

描述
将一棵无穷大满二叉树的结点按根结点一层一层地从左往右编号,根结点编号为1。现给定a,b为两个结点。设计一个算法,返回a、b最近的公共祖先的编号。注意其祖先也可能是结点本身。

测试样例:

2,3
返回:1

解题思路:

子节点与父节点之间的关系为root = child / 2,所以如果a != b,就让其中的较大数除以2, 如此循环直到a == b 即是原来两个数的最近公共祖先

代码实现:

public class LCA {
    public int getLCA(int a, int b) {
       while(a != b) {
        if(a > b) {
            a /= 2;
        }else {
            b /= 2; 
        }
       }
       return a;
    }
}

第五题:求最大连续bit数

描述
求一个int类型数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1
数据范围:数据组数:1≤t≤5 ,1≤n≤500000
进阶:时间复杂度:O(logn) ,空间复杂度:O(1)

输入描述:
输入一个int类型数字

输出描述:
输出转成二进制之后连续1的个数

示例1

输入: 200
输出: 2
说明: 200的二进制表示是11001000,最多有2个连续的1。

解题思路:

根据位运算,获取每一位的二进制值。获取第i位的值: (n >> i) & 1。如果1连续,则计数累加,如果不连续,则从0开始计数

代码实现:

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) { 
            int n = in.nextInt();
            int count = 0;
            int modCount = 0;
            while(n != 0) {
                if((n & 1) == 1) {
                    count++;
                    modCount = Math.max(modCount,count);
                } else {
                    count = 0;
                }
                n >>= 1;
            }
            System.out.println(modCount);
        }
    }
}

你可能感兴趣的:(在线OJ,java,算法,开发语言)