“365算法每日学计划”:1-21打卡

“算法每日学”计划01打卡:
问题描述
对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:
00000
00001
00010
00011
00100
请按从小到大的顺序输出这32种01串。
输入格式
本试题没有输入。
输出格式
输出32行,按从小到大的顺序每行一个长度为5的01串。
样例输出
00000
00001
00010
00011
<以下部分省略>

解题思路与实现

如果有小伙伴很少接触到这种题目的话,可能会觉得有点陌生,不知道从何下手,可能一开始我们能想到“最笨”的方法,但是也觉得挺有“娱乐性”的方法。

System.out.println("00000")
..........
System.out.println("11111")

这种方式是不是也能够得到最后的结果,没错,当然没问题,但是,我们在思考的时候可以一步一步来,尝试多种方法,找到最优解。

这种方法看来不太好,一是不够灵活,二是敲代码很累,所以,改进一下。

image

这种方式是不是能够更加灵活的解决这个问题,这个解决的方式就是我们常说的“暴力破解”,全部用for循环来遍历所有的情况,如果找到符合的情况就输出,但是我们会发现,这个算法的时间复杂度是:O(n^5),这个方法比前一种方法更好了,但是还不是最好的答案。

public static void main(String[] args) {
        for (int i = 0; i < 32; i++) {
            String result = Integer.toBinaryString(i);
            int num = result.length();
                for (int j = 0; j < 5 - num; j++) {
                    result = "0" + result;
                }
                System.out.println(result);

    }

}

再来看看这种方法,这种方法的思路:通过jdk的方法Integer.toBinaryString()获取到每个数字的二进制,因为要求输出的是形如“11111”的五位数字,所以,我们还需要根据得到的二进制的数字的长度,在这个字符串的前面加上5 - num“0”,比如,得到的二进制是1(长度为1),所以在1的前面要加上5-(num=1)等于4个0

是不是特别的简洁,而且这种方法的效率应该也是不错的:O(n),因为这个是jdk提供的方法,在底层是用位移的方法来实现的(注:我们不推荐用jdk的方法来解决,我们尽量用自己思考的方法来解决,就算这个方法“笨”,但是也是自己思考了)。

当然,如果我们换个角度,也可以的到另一种解法。

 public static void main(String args[]){ 
        for(int i=0;i<32;i++){ 
            String str = Integer.toBinaryString(i); 
            switch (str.length()) { 
            case 1: 
                str = "0000"+str; 
                break; 
            case 2: 
                str = "000"+str;
                break;
            case 3:
                str = "00"+str;
                break;
            case 4:
                str = "0"+str;
                break;
            }
                System.out.println(str);

        }
    }
}

这种解法只是用switch-case的方式来解决而已,思路和上面一样。

“算法每日学”计划02打卡:
问题描述
  十六进制数是在程序设计时经常要使用到的一种整数的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个符号,分别表示十进制数的0至15。十六进制的计数方法是满16进1,所以十进制数16在十六进制中是10,而十进制的17在十六进制中是11,以此类推,十进制的30在十六进制中是1E。
  给出一个非负整数,将它表示成十六进制的形式。
输入格式
  输入包含一个非负整数a,表示要转换的数。0<=a<=2147483647
输出格式
  输出这个整数的16进制表示
样例输入
30
样例输出
1E

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Integer n = in.nextInt();
        in.close();
        System.out.println(Integer.toHexString(n).toUpperCase());
    }
}

上面是api,下面看看其他:

这道题本身是没什么难度的,只要用递归处理,当输入的数字大于等于16时,则递归处理该数整除16的值,然后再输出最后一位即可。

但是,我在做的时候,一开始没有考虑到整除16后的值大于9的情况和整除16的次数大于9的情况,结,如下图
这里写图片描述

以后要注意考虑全方面和一定要注意数据范围!

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int a=sc.nextInt();
        int[] b=new int[8];            
//数组b的元素个数由a决定,由于a<=2^32,即a<=16^8
        char[] s={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        if(a>=0&&a<16){
            for(int i=0;i<16;i++){

                int m=a%16;
                if(m==i)
                        System.out.println(s[i]);
                    }
            }
        else{
            int i=0;
            while(a!=0){
                b[i]=a%16;
            a=a/16;
                i++;
            }

        for(int j=i-1;j>=0;j--){
            if(b[j]==10)
                System.out.print("A");
            else if(b[j]==11)
                System.out.print("B");
            else if(b[j]==12)
                System.out.print("C");
            else if(b[j]==13)
                System.out.print("D");
            else if(b[j]==14)
                System.out.print("E");
            else if(b[j]==15)
                System.out.print("F");
            else
                System.out.print(b[j]);
        }
        }
        }
}

“算法每日学”计划03打卡:
问题描述
  数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
  例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
输入格式
  每个测试案例包括2行:
  第一行输入一个整数n(1<=n<=100000),表示数组中元素的个数。
  第二行输入n个整数,表示数组中的每个元素,这n个整数的范围是[1,1000000000]。
输出格式
  对应每个测试案例,输出出现的次数超过数组长度的一半的数,如果没有输出-1。
样例输入
9
1 2 3 2 2 2 5 4 2
9
1 1 1 2 2 2 3 3 3
样例输出
2
-1

    /**
     * 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
     * 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。
     * 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
     */
    public int findMoreThanHalfNum(int[] numbers) {
        int length = numbers.length;
        if (length == 0) return 0;

        int num = numbers[0], count = 1;
        for (int i = 1; i < length; i++) {
            if (numbers[i] == num) count++;
            else count--;
            if (count == 0) {
                num = numbers[i];
                count = 1;
            }
        }
        // Verifying
        count = 0;
        for (int i = 0; i < length; i++) {
            if (numbers[i] == num) count++;
        }
        if (count * 2 > length) return num;
        return 0;
    }

“算法每日学”计划04打卡:
问题描述
    在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
  请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
输入
 输入可能包含多个测试样例,对于每个测试案例,
  输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数。
  输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字。
  接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
输出
对应每个测试案例,
  输出”Yes”代表在二维数组中找到了数字t。
  输出”No”代表在二维数组中没有找到数字t。
样例输入
3 3
5
1 2 3
4 5 6
7 8 9
3 3
1
2 3 4
5 6 7
8 9 10
样例输出
YES
NO

public class Main {
       public boolean Find(int target, int [][] array) {
       int rowCount = array.length;//获取数据的行数
       int colCount = array[0].length; //获取数据的列数
       int i,j;
       i=rowCount-1;
       j=0;

      while((i >=0 )&&(j<colCount)) {
           if (target == array[i][j]) {
                    return true;    
                       }
           else if (target<array[i][j]) {
                i--;
           }else {
               j++;
           } 
       }       
        return false;   
       }
}

“算法每日学”计划05打卡:
问题描述
    理论知识学习,算法基础,理解时间复杂度,理解空间复杂度。
输入
 无
输出

 
  
查看相关资料

“算法每日学计划”06打卡:
问题描述
  给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200
输入格式
  第一行为一个整数n。
  第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000。
输出格式
  输出一行,按从小到大的顺序输出排序后的数列。
样例输入
5
8 3 6 4 9
样例输出
3 4 6 8 9
注:题目简单,解法不少于10种,踊跃发言。

查看相关排序算法,公众号将逐步更新排序算法。

“算法每日学计划”07打卡:
问题描述
  求出区间[a,b]中所有整数的质因数分解。
输入格式
  输入两个整数a,b。
输出格式
  每行输出一个数的分解,形如k=a1a2a3…(a1<=a2<=a3…,k也是从小到大的)(具体可看样例)
样例输入
3 10
样例输出
3=3
4=22
5=5
6=2
3
7=7
8=222
9=33
10=2
5
提示
  先筛出所有素数,然后再分解。
数据规模和约定
2<=a<=b<=10000

import java.util.Scanner;

public class Main {

    /**
     * (1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。
     * (2)如果n>k,但n能被k整除,则应打印出k的值,并用n除以k的商作为新的正整数n,重复执行第一步。
     * (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。
     * 
     * @param joy
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Integer a = sc.nextInt();
        Integer b = sc.nextInt();
        for (int i = a; i <= b; i++) {
            // 输入值大于等于3
            if (i >= 3) {
                String m = "";
                int k = 2;
                int j = i;
                while (j != k) {
                    // 如果n>k,但n能被k整除,则应打印出k的值,并用n除以k的商作为新的正整数n
                    if (j % k == 0) {
                        m = m + k + "*";
                        j = j / k;
                    }
                    // 如果n不能被k整除,则用k+1作为k的值
                    else if (j % k != 0) {
                        k++;
                    }
                }
                m = m + k;
                System.out.println(i + "=" + m);
            } else {
                System.out.println(i + "=" + i);
            }
        }
    }
}

“算法每日学计划”08打卡:
问题描述
  给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关
系是以下4中情况之一:
  1:两个字符串长度不等。比如 Beijing 和 Hebei
  2:两个字符串不仅长度相等,而且相应位置上的字符完全一致(区分大小写),比如
Beijing 和 Beijing
  3:两个字符串长度相等,相应位置上的字符仅在不区分大小写的前提下才能达到完
全一致(也就是说,它并不满足情况2)。比如 beijing 和 BEIjing
  4:两个字符串长度相等,但是即使是不区分大小写也不能使这两个字符串一致。比
如 Beijing 和 Nanjing
  编程判断输入的两个字符串之间的关系属于这四类中的哪一类,给出所属的类的编号

输入格式
  包括两行,每行都是一个字符串
输出格式
  仅有一个数字,表明这两个字符串的关系编号
样例输入
BEIjing
beiJing
样例输出
3
注意:简单题目

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
    Scanner input=new Scanner(System.in);
    String str1=input.nextLine();
    String str2=input.nextLine();
    if(str1.length()!=str2.length()){System.out.println(1);}
    else{
    if(str1.equals(str2)){System.out.println(2);}
    if(str1.toLowerCase().equals(str2.toLowerCase())){System.out.println(3);}
    else{System.out.println(4);}
    }
    }

}

“算法每日学计划”09打卡:
问题描述
  给定一个N阶矩阵A,输出A的M次幂(M是非负整数)
  例如:
  A =
  1 2
  3 4
  A的2次幂
  7 10
  15 22
输入格式
  第一行是一个正整数N、M(1<=N<=30, 0<=M<=5),表示矩阵A的阶数和要求的幂数
  接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值
输出格式
  输出共N行,每行N个整数,表示A的M次幂所对应的矩阵。相邻的数之间用一个空格
隔开
样例输入
2 2
1 2
3 4
样例输出
7 10
15 22

public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        Integer[][] a = new Integer[n][n];
        Integer[][] result = new Integer[n][n];  //保存结果
        for(int i=0;i < n;i ++){
            for(int j=0;j < n;j ++)
                a[i][j] = scanner.nextInt();
        }
        result = a;
        for(int i = 1;i < m;i++)
            result = multiplyMaritx(result, a);

        printMaritx(result);
    }

    /**
     * 打印二维数组
     * @param a
     */
    public static void printMaritx(Integer[][] a){
        for(int i = 0;i < a.length;i ++){
            for(int j = 0;j < a[i].length;j ++)
                System.out.print(a[i][j] + " ");
            System.out.println();
        }
    }

    /**
     * 两个同阶矩阵相乘,返回结果。
     * @param a 第一个矩阵
     * @param b 第二个矩阵
     * @return 相乘的结果
     */
    public static Integer[][] multiplyMaritx(Integer[][] a,Integer[][] b){
        int n = a.length;
        Integer[][] result = new Integer[n][n];  //保存结果
        for(int i = 0;i < n;i ++){
            //遍历二位数组a的行
            for(int j = 0;j < n;j++){
                //遍历二位数组b的列
                Integer c = new Integer(0);
                for(int k = 0;k < n;k ++)
                     //第i行j列的值为a的第i行上的n个数和b的第j列上的n个数对应相乘之和,
                    //其中n为a的列数,也是b的行数,a的列数和b的行数相等
                    c += a[i][k] * b[k][j];
                result[i][j] = c;
            }
        }

        return result;
    }

}

“算法每日学计划”10打卡:
问题描述
亚洲微软研究院所在的希格玛大厦一共有6部电梯。在高峰时间,每层都有人上下,电梯在每层都停。实习生小飞常常会被每层都停的电梯弄得很不耐烦,于是他提出了这样一个办法:
由于楼层并不算太高,那么在繁忙的上下班时间,每次电梯从一层往上走时,我们只允许电梯停在其中的某一层。所有乘客从一楼上电梯,到达某层后,电梯停下来,所有乘客再从这里爬楼梯到自己的目的层。在一楼的时候,每个乘客选择自己的目的层,电梯则自动计算出应停的楼层。
问:电梯停在哪一层楼,能够保证这次乘坐电梯的所有乘客爬楼梯的层数之和最少。
问题分析
该问题本质上是一个优化问题。
  首先为这个问题找到一个合适的抽象模型。
有两个因素会影响结果:乘客的数目和乘客的目的楼层。

思路:假设电梯现在停在第i层,i层以下的人有N1个,i层有N2个,i层以上的人有N3个,当前需要走的楼梯数为Y。当电梯再往上走一层时,i层及i层以下的人一共需要多走N1+N2步,而i层以上的人则一共少走了N3步,所以当N1+N2时,电梯应该继续往上走。

Java代码:

public class Main {
    public static int stopLift(int[] to) {
        if (to.length < 2) {
            return -1;
        }
        int n1 = 0, n2 = to[1], n3= 0, y = 0;
        // 计算一层及以上的人数
        for (int i = 1; i < to.length; i++) {
            n3 += to[i];
            y += (i - 1) * to[i];
        }

        for(int i = 1; i < to.length; i++) {
            n2 = to[i];
            n1 += to[i - 1];
            n3 = n3 - n2;
            if (n1 + n2 >= n3) {
                return i;
            }
        }
        return -1;
    }


    public static void main(String[] args) {

        int[] to = {0, 1, 2 ,3 ,5 ,6, 7};
        System.out.format("电梯应该停在第%d层。", stopLift(to));

    }
}

“算法每日学”11打卡
问题描述:
 写一个算法计算出n的阶乘。
n! = n (n - 1) (n - 2) 3 2 1
1<=n<=10.
输入:
任意一个数字n。
输出:
数字n的阶乘结果。

题目简单,自行思考。

“算法每日学计划”12打卡:
问题描述
  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
  输入一行,包含一个表达式。
输出格式
  输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。

#####解题思路:
注意:解答群里的小伙伴提供的,感谢!
1,初始化两个栈:运算符栈S1和储存中间结果的栈S2;
2,从左至右扫描中缀表达式;
3,遇到操作数时,将其压入S2,这里由于运算数可能大于10,所以如果数字后面一个符号是运算符,则将‘#’入S2栈充当分割线;
4, 遇到运算符时有三种情况:
(4-1) 三种情况下直接入S1栈①S1为空②运算符为‘(’③运算符优先级比S1栈顶运算符的高;
(4-2)如果右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
(4-3) 若运算符优先级小于或等于S1栈顶运算符的优先级,则依次弹出S1栈顶元素,直到运算符的优先级大于S1栈顶运算符优先级;
5, 重复步骤(2)至(5),直到表达式的最右边;
6,将S1中剩余的运算符依次弹出并压入S2;
7,依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式

题解
import java.util.Scanner;
import java.util.Stack;
public class Main{
public static void main(String[] args) {

        // TODO Auto-generated method stub
        Scanner scanner = new Scanner(System.in);
        Stack<Integer> nums = new Stack<Integer>(); // 保存数字
        Stack<Character> opes = new Stack<Character>(); // 保存操作符

        String string = scanner.nextLine();
        int n = 0; // 保存每一个数字
        char[] cs = string.toCharArray();

        for (int i = 0; i < cs.length; i++) {
            char temp = cs[i];
            if (Character.isDigit(cs[i])) {
                n = 10 * n + Integer.parseInt(String.valueOf(cs[i])); // 大于10的数字保存
            } else {
                if (n != 0) {
                    nums.push(n);
                    n = 0;
                }
                if (temp == '(') {
                    opes.push(temp);
                } else if (temp == ')') {
                    while (opes.peek() != '(') { // 括号里面运算完
                        int t = cal(nums.pop(), nums.pop(), opes.pop());
                        nums.push(t);
                    }
                    opes.pop();
                } else if (isType(temp) > 0) {
                    if (opes.isEmpty()) { // 栈为空直接入栈
                        opes.push(temp);
                    } else {
                        // 若栈顶元素优先级大于或等于要入栈的元素,将栈顶元素弹出并计算,然后入栈
                        if (isType(opes.peek()) >= isType(temp)) {
                            int t = cal(nums.pop(), nums.pop(), opes.pop());
                            nums.push(t);
                        }
                        opes.push(temp);
                    }
                }
            }
        }

        // 最后一个字符若是数字,未入栈
        if (n != 0) {
            nums.push(n);
        }
        while (!opes.isEmpty()) {
            int t = cal(nums.pop(), nums.pop(), opes.pop());
            nums.push(t);
        }
        System.out.println(nums.pop());
    }

    // 返回的是运算符的优先级,数字和()不需要考虑
    public static int isType(char c) {
        if (c == '+' || c == '-') {
            return 1;
        } else if (c == '*' || c == '/') {
            return 2;
        } else {
            return 0;
        }
    }

    // 运算次序是反的,跟入栈出栈次序有关
    public static int cal(int m, int n, char c) {
        int sum = -987654321;
        if (c == '+') {
            sum = n + m;
        } else if (c == '-') {
            sum = n - m;
        } else if (c == '*') {
            sum = n * m;
        } else if (c == '/') {
            sum = n / m;
        }
        return sum;
    }
}

“算法每日学计划”13打卡:
问题描述
  给两组数,各n个。
  请调整每组数的排列顺序,使得两组数据相同下标元素对应相乘,然后相加的和最小。要求程序输出这个最小值。
  例如两组数分别为:1 3  -5和-2 4 1
  那么对应乘积取和的最小值应为:
  (-5) 4 + 3 (-2) + 1 * 1 = -25
输入格式
  第一个行一个数T表示数据组数。后面每组数据,先读入一个n,接下来两行每行n个数,每个数的绝对值小于等于1000。
  n<=8,T<=1000
输出格式
  一个数表示答案。
样例输入
2
3
1 3 -5
-2 4 1
5
1 2 3 4 5
1 0 1 0 1
样例输出
-25
6

注意:这个是群里小伙伴的解答。
这里写图片描述

题目思路:最主要的逻辑是弄清楚,题目说和最小,其实就是第一行最小乘以第二行最大,第一行次小乘以第二行次大的和,弄清楚了这一点就迎刃而解了,当然为了减轻运算量,我们可以都从小到大排列,然后通过算法交叉相乘。

题解:

import java.util.Scanner;  

    public class Main {  
        public static void main(String[] args){  
            Scanner in=new Scanner(System.in);  
            int Num=in.nextInt();  
            int i=0,j=0,k=0,c=0;  
            int[] NumArr=new int[Num];  
            for(;c<Num;c++){  
                int m=in.nextInt();//每组数据中有m个元素  
                int[][] a=new int[2][m];  
                for(i=0;i<2;i++){  
                    for(j=0;j<m;j++){  
                        a[i][j]=in.nextInt();  
                    }  
                }  
                int temp=0,sum=0;  
                for(i=0;i<2;i++){  
                    for(j=0;j<m-1;j++){  
                        for(k=j;k<m;k++){  
                            if(a[i][j]>a[i][k]){  
                            temp=a[i][j];  
                            a[i][j]=a[i][k];  
                            a[i][k]=temp;  
                            }  
                        }  
                    }  

                }  
                for(j=0;j<m;j++){  
                    sum+=(a[0][j]*a[1][m-j-1]);  
                }  
                NumArr[c]=sum;  
            }  
            for(c=0;c<Num;c++){System.out.println(NumArr[c]);}  
        }  

    }

“算法每日学计划”14打卡:
描述
输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符。
输入
第一行输入一个数N,表示有N组测试数据。后面的N行输入多组数据,每组输入数据都是占一行,有三个字符组成,之间无空格。
输出
对于每组输入数据,输出一行,字符中间用一个空格分开。
样例输入
2
qwe
asd
样例输出
e q w
a d s

java:

import java.util.*;

public class Main {     //程序入口
    public static void main(String[] args) throws Exception {   //应程序要求,OJ规范,抛出异常
        Scanner cin = new Scanner(System.in);   //采用Scanner读取控制台
        int a = cin.nextInt();  //记录数据组数

        for (int n=a; n>=1; n--) {      //每组
            char m, v, p;   //记录三个char字符
            String s1 = cin.next();     //Scanner读入的是一个String
            //读取字符串中的字符
            m = s1.charAt(0);
            v = s1.charAt(1);
            p = s1.charAt(2);

            sort1(m, v, p); //方法调用
        }
    }

    //方法:输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符。
    public static void sort1(char a, char b, char c) {
        char t1 = a;  //分别定义三个char变量用于记录形参传来的三个值
        char t2 = b;
        char t3 = c;
        char t; //临时变量
        //三个数字,按增序输出
        if (t1 > t2) { //如果第一个数大于第二个数,交换第一个数和第二个数 
            t = t1; //交换t1和t2 
            t1 = t2;
            t2 = t;
        }
      //此时第一个数一定比第二个数小 
        if(t3 < t1)//若第三个数比t1小 
            System.out.println(t3 + " " + t1 + " " + t2 + "\n");
        else if(t3 > t2) //若第三个数比t2大 
            System.out.println(t1 + " " + t2 + " " + t3 + "\n");
        else //第三个数介于t1和t2之间 
            System.out.println(t1 + " " + t3 + " " + t2 + "\n");
    }
}

如果有小伙伴用c++的话,可以看看这个,效率更好:

#include <iostream>
using namespace std;

void sort1(char a, char b, char c)  //输入三个字符,按字符的ASCII码从小到大的顺序输出这三个字符
{
  char t1 = a;  //分别定义三个char变量用于记录形参传来的三个值
  char t2 = b;
  char t3 = c;
  char t; //临时变量
  //三个数字,按增序输出 
  if (t1 > t2)  //如果第一个数大于第二个数,交换第一个数和第二个数 
  {
    t = t1; //交换t1和t2 
    t1 = t2;
    t2 = t;
  }

  //此时第一个数一定比第二个数小 
  if(t3 < t1) //若第三个数比t1小 
    cout << t3 << " " << t1 << " " << t2 << endl; 
  else if(t3 > t2) //若第三个数比t2大 
    cout << t1 << " " << t2 << " " << t3 << endl;
  else //第三个数介于t1和t2之间 
    cout << t1 << " " << t3 << " " << t2 << endl;

} 

int main()  //程序入口 
{
  int a;  //记录循环次数 

  cin >> a;
  for (int n=a; n>=1; n--) 
  {
    char a,b,c;
    cin >> a >> b >> c;
    sort1(a, b, c);
  }

  return 0;
}

“算法每日学计划”15打卡:
描述
输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符。
输入
第一行输入一个数N,表示有N组测试数据。后面的N行输入多组数据,每组输入数据都是占一行,有三个字符组成,之间无空格。
输出
对于每组输入数据,输出一行,字符中间用一个空格分开。
样例输入
2
qwe
asd
样例输出
e q w
a d s

注意:群里小伙伴解答,感谢!
这里写图片描述

“算法每日学计划”16打卡:
时间限制:1.0s 内存限制:256.0MB
问题描述
已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。
输入格式
输入一个正整数N。
输出格式
输出一个整数,表示你找到的最小公倍数。
样例输入
9
样例输出
504
数据规模与约定
1 <= N <= 106。

注意:群里小伙伴解答,感谢!

解题思路:
思路分析:最大 最小公倍数,联想到两个数的求最大最小公倍数,即两个数的乘积(注:连续的两个自然数是互斥的)。

同样,我们可以拿最后三个数来做考虑。

1.当n为奇数时,n,n-1,n-2为奇偶奇,里面只有一个偶数,所以不会有2这个因子。这三个数相差不到3,所以也不会有因子3,故符合题意。

2.当n为偶数时,n,n-1,n-2为偶奇偶,此时n,n-2肯定含有因子2,所以除于2不值得。所以考虑将n-2 换成n-3,变成奇偶奇,此时也有一个问题,

n和n-3,如果n%3==0,则除于3更不值得。仍根据奇偶奇的原则,变动偶数n为n-2,此时换成n-1,n-2,n-3和1情况一样。故此时符合题意。
这里写图片描述

“算法每日学计划”16打卡:
描述
现在,有一行括号序列,请你检查这行括号是否配对。
输入
第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有”[“,”]”,”(“,”)”四种字符
输出
每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No
样例输入
3
[(])
(])
([])
样例输出
No
No
Yes

使用栈的,对字符串的单个字符进行处理。如果栈为空,则入栈,如果不为空,则判断栈顶的字符与当前字符是否能够匹配()或者[],如果匹配,则将栈顶字符出栈,否则入栈。

最后如果栈为空,则匹配,否则不匹配。源码:

public static void main(String[] args) {  
        Scanner sc = new Scanner(System.in);  

        int n= sc.nextInt();

        Stack<Character> stack = null;  

        while(n!=0){  

            //从控制台读入一个测试字符串[]() [(])  
            String str = sc.next();  
            //如果该输入字符串为奇数,说明不匹配  
            if(str.length() % 2 == 1){  
                System.out.println("No");  
            }else{  
                //说明字符是偶数  
                stack = new Stack<Character>();  
                for(int i=0;i<str.length();i++){  
                    if(stack.isEmpty()){  
                        //如果栈是空的  
                        stack.push(str.charAt(i));  
                    }else if(stack.peek() == '[' && str.charAt(i) == ']' || stack.peek() == '(' && str.charAt(i) == ')'){  
                        //说明此时栈中字符不是空的,并且符合,  
                        stack.pop();  
                    }else{  

                        stack.push(str.charAt(i));  
                    }  
                }  

                if(stack.isEmpty()){  
                    //如果栈是空的,说明括号匹配  
                    System.out.println("Yes");  
                }else{  
                    //说明栈不为空,括号不匹配  
                    System.out.println("No");  
                }  
            }  

            n--;  
        }  

    }

“算法每日学计划”17打卡:
时间限制:5000 ms | 内存限制:65535 KB
难度:3
描述
给定一整型数列{a1,a2…,an},找出连续非空子串{ax,ax+1,…,ay},使得该子序列的和最大,其中,1<=x<=y<=n。
输入
第一行是一个整数N(N<=10)表示测试数据的组数)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的一行里有n个整数I(-100=<I<=100),表示数列中的所有元素。(0<n<=1000000)
输出
对于每组测试数据输出和最大的连续子串的和。
样例输入
1
5
1 2 -1 3 -2
样例输出
5

注意:群里小伙伴解答,感谢!
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

解题思路:
动态规划:

  • f[i]表示到a[i]为止,包含a[i]的最长连续非负和的子串。

  • f[i-1]为正则f[i] = f[i - 1] + a[i];否则f[i] = a[i];

import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Scanner;

public class Main{
    public static void main(String[] args) {
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int t = cin.nextInt();
        while (t-- > 0) {
            int n = cin.nextInt();
            int[] a = new int[n + 5];
            for (int i = 1; i <= n; i++) {
                a[i] = cin.nextInt();
            }
            int[] f = new int[n + 5];
            Arrays.fill(f, 0);
            f[1] = a[1];
            for (int i = 2; i <= n; i++) {
                if (f[i - 1]  > 0)
                    f[i] = f[i - 1] + a[i];
                else
                    f[i] = a[i];
            }
            int max = Integer.MIN_VALUE;
            for (int i = 1; i <= n; i++) {
                if (max < f[i]) {
                    max = f[i];
                }
            }
            System.out.println(max);
        }
    }

}

“算法每日学计划”18打卡:
  问题描述
  编写一个程序,读入一组整数,这组整数是按照从小到大的顺序排列的,它们的个数N也是由用户输入的,最多不会超过20。然后程序将对这个数组进行统计,把出现次数最多的那个数组元素值打印出来。如果有两个元素值出现的次数相同,即并列第一,那么只打印比较小的那个值。
  输入格式:第一行是一个整数N,N £ 20;接下来有N行,每一行表示一个整数,并且按照从小到大的顺序排列。
  输出格式:输出只有一行,即出现次数最多的那个元素值。
输入输出样例
样例输入
5
100
150
150
200
250
样例输出
150

注意:群里小伙伴解答,感谢!
这里写图片描述

这里写图片描述

“算法每日学计划”19打卡:
描述
现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度。如果左右有等距离长度素数,则输出左侧的值及相应距离。
如果输入的整数本身就是素数,则输出该素数本身,距离输出0
输入
第一行给出测试数据组数N(0<N<=10000)
接下来的N行每行有一个整数M(0<M<1000000),
输出
每行输出两个整数 A B.
其中A表示离相应测试数据最近的素数,B表示其间的距离。
样例输入
3
6
8
10
样例输出
5 1
7 1
11 1
注意:打卡啦,打卡啦。

解答:
这里写图片描述

“算法每日学计划”20打卡:
描述
在nn方陈里填入1,2,…,nn,要求填成蛇形。例如n=4时方陈为:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
输入
直接输入方陈的维数,即n的值。(n<=100)
输出
输出结果是蛇形方陈。
样例输入
3
样例输出
7 8 1
6 9 2
5 4 3

注意: 群里小伙伴解答,感谢!
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

“算法每日学计划”21打卡:
描述
给定两个数m,n,其中m是一个素数。
将n(0<=n<=10000)的阶乘分解质因数,求其中有多少个m。
输入
第一行是一个整数s(0<s<=100),表示测试数据的组数
随后的s行, 每行有两个整数n,m。
输出
输出m的个数。
样例输入
2
100 5
16 2
样例输出
24
15

注意: 群里小伙伴解答,感谢!
这里写图片描述
这里写图片描述


 上一篇
java设计模式:简单工厂模式 java设计模式:简单工厂模式
一、什么是简单工厂模式简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。 二、简单工厂模式的角色和职责1.工厂(Creator)角色 简单工厂模式的核心,它负
本篇 
“365算法每日学计划”:1-21打卡 “365算法每日学计划”:1-21打卡
“算法每日学”计划01打卡:问题描述对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:0000000001000100001100100请按从小到大的顺序输出这32种01串。输入格式本试题没有输入。输出格
  目录