算法(3)

news2025/1/11 4:14:26

喝汽水

两瓶即可换一瓶

import java.util.*;
public class Main {
    public static void main(String[] args) {
        //剩2个空瓶子时,可以先找老板借一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。 
        //也就是说2个空瓶子即可换一瓶汽水喝,而且喝完之后手里也没有空瓶子。
        Scanner in = new Scanner(System.in);
        //f[i] = f[i/3+i%3]+i/3  看 f[i/3+i%3]能对多少
        int dp[] = new int[101];
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 1;
        dp[3] = 1;
        dp[4] = 2;
        int index = 5;
        for (; index <= 100; index++) {
            dp[index] = dp[index / 3 + index % 3 ] + index / 3;
        }
        while (in.hasNext()) {
            int x = in.nextInt();
            if (x == 0) return;
            System.out.println(dp[x]);
        }
    }
}

兔子问题,兔子不死,两个月就长大,生兔子。

f[i] = f[i-1]+f[i-2]; 斐波那契数列

杨辉三角变形 - 推规律

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XsI2JW7Z-1690389939897)(https://s2.loli.net/2022/07/09/GIQbhajw3EAfvVB.png)]

放苹果

n个苹果放m哥盘子,问有多少种放法,可以空盘。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //dp[i][j] 表示i个苹果放 j个盘子的方案书
        // dp[i][j] = dp[i][j-1] 表示j个盘子忽略 (i<j)时候一定有空盘子,其方案书就等于 dp[i][i] 相当于空盘子不用管
        //dp[i][j] = dp[i-j][j] 表示j个盘子,每个盘子放1个后,再去划分i-j个橘子
        int n ,m;
        n = in.nextInt();
        m = in.nextInt();
        
        int dp[][] = new int [n+1][m+1];
        for(int i=0;i<=m;i++) dp[0][i] = 1;
        
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
               if(i<j) dp[i][j] = dp[i][j-1];
                else{
                    dp[i][j] = dp[i][j-1]+dp[i-j][j];
                }
            }
        }
        
        System.out.println(dp[n][m]);
        
    }
}

合唱队

N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<…<Ti-1 <Ti+1&& Ti+1>…>TK。

你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形.

两个dp,记录从左往右或者从右往左的最长上升子序列,dp[i]是包含i在内的最长上升子序列长度。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        int n = Integer.parseInt(br.readLine());

        str = br.readLine();
        int [] arr  = Arrays.stream(str.split(" ")).mapToInt(
                          Integer::parseInt).toArray();

        int left [] = new int [arr.length];
        int right [] = new int [arr.length];
        int len = arr.length;

        left[0] = 1;
        right[len - 1] = 1;

        //left[i]表示从左往右遍历前i个人(包括第i个人在内) 递增子序列的长度,这点很重要,
        //最后计算的时候 left[i]+right[i] -1  减1是减去那个重复的第i个人。
        //right[i] 下标i右边的递增子序列
        
        for (int i = 1; i < len; i++) {
            left[i] =1;
            for (int j = 0; j < i; j++) {
                if (arr[j] < arr[i]) left[i] = Math.max(left[j] + 1,left[i]);
            }
        }

        for (int i = len - 2; i >= 0; i--) {
            right[i]=1;
            for (int j = len - 1; j > i; j--) {
                if (arr[j] < arr[i]) right[i] =  Math.max(right[j] + 1,right[i]);
            }
        }

        int max = 0;
        for (int i = 0; i < len; i++) {
            if (left[i] + right[i]-1 > max) {
                max = left[i] + right[i]-1;
            }
            //System.out.println(left[i]+" "+right[i]);
        }
        
        System.out.println(len-max);

    }
}

字符串排序

编写一个程序,将输入字符串中的字符按如下规则排序。

规则 1 :英文字母从 A 到 Z 排列,不区分大小写。

如,输入: Type 输出: epTy

规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。

如,输入: BabA 输出: aABb

规则 3 :非英文字母的其它字符保持原来的位置。

如,输入: By?e 输出: Be?y

数据范围:输入的字符串长度满足 1≤n≤1000 1≤n≤1000

根据字典序(26个字母)从左往右遍历元素,元素是对应字典序,就摘选元素进行输出,既考虑元素输入循序,也考虑了字典序。

import java.util.*;
public class Main{
    public static void main(String a[]){
        Scanner in = new Scanner (System.in);
        String str = in.nextLine();
        char chs[] = str.toCharArray();
        ArrayList<Character> list = new ArrayList<>();
        
        //排序 主要看的排序的稳定性,对于其他字符不进行swap即可。其他元素交换。
        // 注意稳定性
        int len = chs.length;
        //基数排序
        for(int i=0;i<26;i++){
            for(int j=0;j<len;j++){
                if(chs[j]-'a'==i||chs[j]-'A'==i){
                   list.add(chs[j]); 
                }
            }
        }
        
        //
        for(int i=0,k=0;(i<len)&&k<list.size();i++){
            if((chs[i]>='a'&&chs[i]<='z')||(chs[i]>='A'&&chs[i]<='Z')){
                chs[i] = list.get(k++);
            }
        }
        System.out.println(new String(chs));
        
    }
}

密码截取

求最长回文串,中心拓展。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        //最长回文串
        str = br.readLine();
        str = process(str);
        
        int max = 1;
        char arr[] = str.toCharArray();
        for(int i=0;i<str.length();i++){
            int t = spread(i,arr);
            if(max<t) max = t;
        }

        System.out.println(max-1);
    }

    static int spread(int x, char [] arr) {
        int left = x - 1, right = x + 1;
        int count = 1;
        while (left >= 0 && right < arr.length) {
            if (arr[left] == arr[right])
                count++;
             else break;
            left--;
            right++;
           
        }
        return count;
    }


    static String process(String str) {
        StringBuilder bu = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            bu.append("#" + str.charAt(i));
        }
        bu.append("#");
        return bu.toString();
    }

}

称砝码-求种数

import java.util.*;
public class Main {
    public static void main(String s[]) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m[] = new int[n];
        int x[] = new int[n];
        int sum = 0;

        for (int i = 0; i < n; i++) {
            m[i] = in.nextInt();
        }
        for (int i = 0; i < n; i++) {
            x[i] = in.nextInt();
            sum += m[i] * x[i];
        }


        boolean dp[] = new boolean [sum + 1];

        // System.out.println(dp[sum]);

        dp[0] = true;

    	//保证第i件物品只用j次
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < x[i]; j++) {
                for (int k = sum; k >=m[i]; k--) {
                   if(dp[k-m[i]]) dp[k] = true;
                }
            }
        }

        int count = 0;
        for (int i = 0; i <= sum; i++) {
//             if(dp[i]) System.out.println(i+" "+dp[i]);
            if (dp[i]) count++;
        }
        System.out.println(count);
    }

}

迷宫-求路径

  • 唯一解,起点左上角,终点右下角,那就dfs,优先往下、往右走,没走一步将原有的路径封闭,表示已经走过,且将试探的下一步路径放入队列尾部,直到找到终点或者无路可走那就将队列尾部节点出队,表示该节点已经是死路。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
// import java.util.Stack;
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str1 = br.readLine();
        int n = Integer.parseInt(str1.split(" ")[0]);
        int m = Integer.parseInt(str1.split(" ")[1]);
        int maze [][] = new int [n][m];
        for (int i = 0; i < n; i++) {
            str1 = br.readLine();
            int a[] = Arrays.stream(str1.split(" ")).mapToInt(Integer::parseInt).toArray();
            for (int j = 0; j < m; j++)
                maze[i][j] = a[j];
        }

        LinkedList<Node> stack = new LinkedList<>();
        stack.push(new Node(0, 0));

        boolean [][] isVisit = new boolean [n][m];

        while (!stack.isEmpty()) {
            Node node = stack.peek();
            if (node.x == n - 1 && node.y == m - 1) break;
            visit(node, maze, stack);
        }

        while (!stack.isEmpty()) {
            Node node = stack.removeLast();
            System.out.println("(" + node.x + "," + node.y + ")");
        }

    }

    static void visit(Node node, int maze[][], LinkedList  stack) {

        int n = maze.length;
        int m = maze[0].length;
        int x = node.x;
        int y =  node.y;
        
        if (x < n - 1 && maze[x + 1][y] != 1) {
            stack.push(new Node(x + 1, y));
            maze[x + 1][y] = 1;
            return ;
        }
        if (y < m - 1 && maze[x][y + 1] != 1) {
            stack.push(new Node(x, y + 1));
            maze[x][y + 1] = 1;
            return ;
        }
        if (x > 0 && maze[x - 1][y] != 1) {
            stack.push(new Node(x - 1, y));
            maze[x - 1][y] = 1;
            return ;
        }
        if (y > 0 && maze[x][y - 1] != 1) {
            stack.push(new Node(x, y - 1));
            maze[x][y - 1] = 1;
            return ;
        }
       //不能往下走 回滚
       Node no = (Node)stack.pop();
//        maze[no.x][no.y] = 1;
    }
}

class Node {
    public int x;
    public int y;
    public Node(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

从单向链表中删除指定值的节点

image-20220711185436615

思路 : 因为链表中不能存在val相同的节点,所以插入 p,e 。就看前置节点p是否存在,p存在那就是在后插新节点e。如果p未遍历到,e已经遍历到了,那就是在e节点前插入新的节点p。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line  = br.readLine();
        String [] ss = line.split(" ");
        int n = Integer.parseInt(ss[0]);
        int h  =  Integer.parseInt(ss[1]);
        Node head = new Node(h);
        for(int i=0;i<2*(n-1);i+=2){
            int p = Integer.parseInt(ss[i+2]);
            int t = Integer.parseInt(ss[i+3]);
//             System.out.println(p+" "+ t);
            head = add(head,t,p);
//             print(head);
        }
      
         int r  =  Integer.parseInt(ss[ss.length-1]);
         head = remove(head,r);
         print(head);
    }
    
    static Node remove(Node head,int x){
        Node pre = null;
        Node tem = head;
        while(tem!=null){
            if(tem.val == x){
                if(pre==null) return head.next;
                pre.next = tem.next;
                return head;
            }
            pre = tem;
            tem = tem.next;
        }
        return head;
    }
    
// t前置节点 插入在后置节点s之前
     static Node add(Node head,int t,int s){
        Node pre = null;
        Node tem = head;
        while(tem!=null){
            //后置节点s有值了 说明t没有需要新建
            if(tem.val == s){
                 Node te = new Node(t);
                 te.next = tem;
                if(pre==null){
                    return te;
                }
                pre.next = te;
                return head;
            }
            // 前置节点t有值了 说明后置节点s没有
            if(tem.val==t){
                Node ss = new Node(s); 
                ss.next = tem.next;
                tem.next = ss;
                return head;
            }
            pre = tem;
            tem = tem.next;
        }
        return head;
    }
    
    static void print(Node head){
        while(head!=null){
            System.out.print(head.val+" ");
            head = head.next;
        }
        System.out.println();
    }
}
class Node{
    int val;
    Node next;
    public Node(int x){
        val = x;
    }
}

四则运算

双栈记录操作符和操作数

  1. 运算符优先级* / 高于+ -

  2. 数字入栈

  3. 左括号入栈,留匹配有括号

  4. 遇到右扩号就对()中进行计算,要求提前处理括号中表达式,对括号中的计算结果只有(10)或者(12+12)或者(1+2*3)好处理,如(1-2+3)不好处理,这就要求第五步。

  5. 遇到运算符,那就运算符

    • 如果是如(- 或者是表达式第一个字符,那就添加数0,用于计算 0 - 4 = -4

    • 否则就是正常表达式要求 当前的运算符优先级高于or 等于操作符栈顶的优先级。

      形如 1-2+3,遇到+ ,那么-可以提前运算。遇到1+2*3-4 遇到-才计算*以及+。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.HashMap;
// import java.util.System;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = br.readLine();
        String ss = line.replaceAll("\\[", "(").replaceAll("\\]", ")").replaceAll("\\{",
                    "(")
                    .replaceAll("\\}", ")");
        char chs [] = ss.toCharArray();

        //System.out.println(chs);

        HashMap<Character, Integer> map  = new HashMap<>();
        map.put('+', 1);
        map.put('-', 1);

//         map.put('(', -1);

        map.put('*', 3);
        map.put('/', 3);

        Stack<Double> nums = new Stack<>();
        Stack<Character> ops = new Stack<>();

        for (int i = 0; i < chs.length; i++) {

            if (chs[i] == '(') ops.push(chs[i]);
            //数字
            else if (Character.isDigit(chs[i])) {
                double num = 0.0;
                while (i < chs.length && Character.isDigit(chs[i])) {
                    num = num * 10.0 + (chs[i] - '0');
                    i++;
                }
//                 System.out.println(num);
                nums.push(num);
                i--;
            } else if (chs[i] == ')') {
//                  System.out.println(chs[i]);
                //遇到 ) 直到遇到 ( 计算括号中的结果
                while (!ops.isEmpty() && ops.peek() != '(') {
                    char c = ops.pop();
                    double x = nums.pop();
                    double y = nums.pop();
//                     System.out.println(y + "" + c + "" + x);
                    nums.push(cal(y, x, c));
                }
                if (!ops.isEmpty()) ops.pop();
                //运算符
            } else {
                //说明遇到负数 第一个字符 或者前一个字符是 (
                if ((i == 0 || chs[i - 1] == '(') && (chs[i] == '+' || chs[i] == '-')) {
                    nums.push(0.0);
                }
//                 ops.push(chs[i]);
                //当前符号优先级 高于 栈顶就运算
                while (!ops.isEmpty()  && ops.peek() != '('&&
                        map.get(ops.peek()) >= map.get(chs[i])) {
                    char c = ops.pop();
                    double x = nums.pop();
                    double y = nums.pop();
//                     System.out.println(y + "" + c + "" + x);
                    nums.push(cal(y, x, c));
                }
                ops.push(chs[i]);
            }
        }

        while (!ops.isEmpty()) {
            char c = ops.pop();
            double x = nums.pop();
            double y = nums.pop();
            nums.push(cal(y, x, c));
//             System.out.println(y + "" + c + "" + x);
        }

        System.out.printf("%.0f", nums.peek());

    }


    static double cal(double a, double b, char op) {
        switch (op) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                return a / b;
            default:
                return 0.0;
        }
    }

}

编辑距离

初始化dp[0][0]表示的是字符串a和b的空字符串编辑距离为0,dp[0][j] = j;这时为了更好的比较像 a , cdfsa这样的情况。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
// import java.lang.Math;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String A = br.readLine();
        String B = br.readLine();
        
        char [] a = A.toCharArray();
        char [] b= B.toCharArray();
        int dp [][] = new int[a.length+1][b.length+1];
        
        for(int i=0;i<=a.length;i++)
        Arrays.fill(dp[i],Math.max(a.length,b.length));
        
        dp[0][0] = 0;
        for(int i=0;i<=a.length;i++){
           dp[i][0] = i;
        }
        
        for(int i=0;i<=b.length;i++){
           dp[0][i] = i;
        }
        
        for(int i=1;i<=a.length;i++){
            for(int j=1;j<=b.length;j++){
                if(a[i-1]==b[j-1]) {
                    dp[i][j] = Math.min(dp[i-1][j-1],dp[i][j]);
                    //b 插入一个字符 
//                    if(i>=2) dp[i][j] = Math.min(dp[i-2][j-1]+1,dp[i][j]);
//                       //a 插入一个字符 
//                     if(j>=2) dp[i][j] = Math.min(dp[i-1][j-2]+1,dp[i][j]);
                }
                else {
                //不等  删除一个 和插入类似
                    dp[i][j] = Math.min(dp[i-1][j]+1,dp[i][j]);
                    dp[i][j] = Math.min(dp[i][j-1]+1,dp[i][j]);
                   // 替换 或者 插入
                   // 如 abcd  acd  b与c比较 往ac之间插入b
                    dp[i][j] = Math.min(dp[i-1][j-1]+1,dp[i][j]);
                }
               //System.out.println(i+" "+j+" "+dp[i][j]);
            }
        }
        
        System.out.println(dp[a.length][b.length]);
        
    }
}

入栈出栈序列问题

计数

img

Cnm = Cnm-1 + Cn-1m-1

给定入栈序列,判断能否得到指定的出战序列

链接

  • 通过辅助栈A判断,对入栈序列每个元素入栈,若A栈顶元素不等于出栈序列元素B,就入栈,直到A栈顶元素等于B就出栈,同时遍历下一个出战序列元素B1,再次判断A栈顶元素是否和B1相等,不同继续入栈,相等出栈,最后栈A为空就是可以,否则不可以。
class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> stack = new Stack<>();
        int i = 0;
        for(int num : pushed) {
            stack.push(num); // num 入栈
            while(!stack.isEmpty() && stack.peek() == popped[i]) { // 循环判断与出栈
                stack.pop();
                i++;
            }
        }
        return stack.isEmpty();
    }
}


给定入栈序列,求出所有的出战序列

#include <iostream>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;

// input: 输入序列,i 表示输入到第 i 个,N 表示有 N 个输入元素; seq: 某一个输出序列; result : 存储所有的序列
void GetAllSequence(const int* input, int i, const int N, stack<int> &stk, vector<int> &seq,vector<vector<int> > &result) {
    if (i == N) {
        // 输入序列全部入栈完毕,只能出栈。将栈中的元素添加到seq 的后面, 保存 seq
        if (!stk.empty()) {
            int top = stk.top();
            seq.push_back(top);
            stk.pop();
            GetAllSequence(input, i, N, stk, seq, result); // 保持 i == N,递归地将 stk 元素复制到 seq
            stk.push(top); //回溯
            seq.pop_back();
        } else {
            result.push_back(seq); // 保存结果
        }
    } else {
        // 对于一个输入元素,可以入栈;可以不入,弹出栈中已有元素
        // 入栈
        stk.push(input[i]);
        GetAllSequence(input, i+1, N, stk, seq, result); // 向 i+1 递归
        stk.pop(); // 回溯,恢复栈之前的状态

        // 出栈
        if (!stk.empty()) {
            int top = stk.top(); //记录
            stk.pop();
            seq.push_back(top);
            GetAllSequence(input, i, N, stk, seq, result); // 保持 i 不变
            seq.pop_back(); // 回溯,恢复栈和序列之前的状态
            stk.push(top);
        }
    }
}

int main()
{
    int input[] = {1,2,3}; // 输入序列
    const int N = sizeof(input)/sizeof(input[0]);
    vector<vector<int> > result; //保存所有序列
    vector<int> seq;
    stack<int> stk;
    GetAllSequence(input, 0, N, stk, seq, result);
    for (int i = 0; i < result.size(); i++) {
        for (int j = 0; j < result[0].size(); j++) {
            cout << result[i][j] << " ";
        }
        cout << endl;
    }
}

真分数分解

如 2/4 分解为 1/3+1/6;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));


        while (br.ready()) {
            String str = br.readLine();
//             long a[] = Arrays.stream(str.split("/")).mapToLong(Long::parseLong).toArray();
            String ss[] = str.split("/");
            long a[] = new long[2];
            a[0] = Long.parseLong(ss[0]);
            a[1] = Long.parseLong(ss[1]);

            StringBuilder sb = new StringBuilder();
            // System.out.println(a[0]+" "+a[1]);
//             if (a[0] == 1) {
//                 sb.append("1/" + a[1]);
//             }
//              System.out.println(1%0);

            boolean first = true;

            while (true) {

                if (a[0] == 1) {
                    if (first) {
                        sb.append("1/" + a[1]);
                        first = false;
                    } else sb.append("+" + "1/" + a[1]);
                    break;

                } else {

                    long x = a[1] / a[0] + 1;
//                 System.out.println(x);

                    if (first) {
                        sb.append("1/" + x);
                        first = false;
                    } else sb.append("+" + "1/" + x);

                    long z = a[0] * x - a[1];
                    long m = x * a[1];
                    long g = gcd(m, z);

                    z /= g;
                    m /= g;

                    a[0] = z;
                    a[1] = m;
                }

            }

            System.out.println(sb.toString());
        }


    }

    static long gcd(long a, long b) {
        while ((a % b) != 0) {
            //System.out.println(a + " " + b);
            long t = b;
            b = a % b;
            a = t;
        }
        return b;
    }
}

优化 long x = a[1] / a[0] + 1计算时候,出现除得尽的就相当于是分子和分母能化成分子为1的情况,那么这就是最后一个真分数,直接退出即可。省去gcd部分。

// 有一说一,他们说这是数学家提出的算法,但是我自己也想出来了这个算法,巨开心哈哈哈
import java.io.*;
public class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while((str = br.readLine())!=null) {
            String[] ss = str.split("/");
            long a = Integer.parseInt(ss[0]);
            long b = Integer.parseInt(ss[1]);
            long t;
            StringBuilder sb = new StringBuilder();
            while(a != 0) {
                t = b/a + (b%a==0?0:1);
                if (b % t == 0 && a >= t) {
                    a -= b/t;
                    sb.append('1').append('/').append(t).append('+');
                } else {
                    a = a * t - b;
                    b = b * t;    // 这里可能溢出,所以都用long
                    if(a!=0)sb.append('1').append('/').append(t).append('+');
                    else sb.append('1').append('/').append(t);
                }
                if(a == 1) {
                    sb.append('1').append('/').append(b);
                    break;
                }
            }
            System.out.println(sb);

        }
    }
}


最长上升子序列长度

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.LinkedList;



public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        int n = Integer.parseInt(str);
        String z[] = br.readLine().split(" ");

        if (n <= 1)  {
            System.out.println(0);
            return ;
        }


        int arr[] = new int [z.length];
        int []  B = new int[z.length];

        int i = 0;
        for (String e : z) {
            arr[i++] = Integer.parseInt(e);
        }
        int max = -1;
        for ( i = 0; i < n; i++) {
            if (max == -1) {
                B[++max] = arr[i];
            } else {
                if (arr[i] > B[max]) {
                    B[++max] = arr[i];
                } else if (arr[i] < B[max]) {
                    int index =  qs(B, max, arr[i]);
                    B[index] = arr[i];
                }

            }
//            for(int j=0;j<=max;j++){
//                  System.out.print(B[j]+" ");
//            }
//              System.out.println();
        }

        System.out.println(max + 1);

    }

    //在B中找大于等于指定数值t的 下标
    static int  qs(int b[], int s, int t) {
        int l = 0, r = s;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (b[mid] >= t) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
       // System.out.println(l);
        return l;
    }
}

举证估算量

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        HashMap<Character, Mutrix> map = new HashMap<>();

        int i = 0, sum = 0;
        while (n > 0) {
            String [] str = br.readLine().split(" ");
            map.put((char)('A' + i), new Mutrix(Integer.parseInt(str[0]),
                                                Integer.parseInt(str[1])));
//             System.out.println((char)('A'+i));
            i++;
            n--;
        }


        Stack<Character> stack  = new Stack<>();
        char [] chs = br.readLine().toCharArray();
        stack.push(chs[0]);

        int index = 1;

        while (!stack.isEmpty() && i < chs.length) {
            if (chs[index] != ')') stack.push(chs[index]);
            else {
                char tem[] = new char[2];
                int j = 0;
                while (!stack.isEmpty() && stack.peek() != '(') {
                    tem[j++] = stack.pop();
                }
                
                if (stack.peek() == '(') stack.pop();
//                 System.out.println(tem[1] + " " + tem[0]);
//                 sum += cal(tem[1], tem[0], map);
                
                Mutrix m1 = map.get(tem[1]);
                Mutrix m2 = map.get(tem[0]);
                sum+= m1.r*m1.l*m2.l;
                //栈空 计算结束
                if(stack.isEmpty()) break;
                
                map.put(tem[1], new Mutrix(m1.r, m2.l));
                stack.push(tem[1]);
            }
            index++;
        }

        System.out.println(sum);

    }

//     static int cal(char a, char b, int i, HashMap<Character, Mutrix> map) {

//         return m1.r * m1.l * m2.l;
//     }

}

class Mutrix {
    public int r;
    public int l;
    public Mutrix(int r, int l) {
        this.r = r;
        this.l = l;
    }
}

求解立方根

泰勒公式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p0HU20Q2-1690389939898)(https://s2.loli.net/2022/07/13/ujD8NUePKCpVRmE.jpg)]

设f(x) = x3 -A,由泰勒展开 f(x) = x3-A - 3x2 (x-x0)前两项即可,要求f(x)->0时x的值。所以

(x3 -A) /(3x2) = x - x0 ,得到递推计算公式 xn = xn-1 - (x3n-1 -A) /(3x2n-1)。此时代入xn-1,迭代计算xn,直到误差满足要求。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        double d = Double.parseDouble(reader.readLine());
        double xa  = 1.0, xb  = 0.0;
        // f(x) - A 计算误差 xn+1 = xn - (xn^3-A)/(3xn^2)
        while (true) {
            double to  = Math.pow(xa, 3.0) - d;
            if (Math.abs(to) < 1e-5) break;
            xb = xa - to / (3 * Math.pow(xa, 2.0));
            xa = xb;
            //System.out.println(xa);
        }
        
        System.out.printf("%.1f\n",xa);

    }
}

递归回溯

24点游戏算法

image-20220713171431963

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String [] number = br.readLine().split(" ");
        
        int[] nums = new int[4]; // 存放数字
        boolean[] visit = new boolean[4]; // 存放对应位置数字的使用状态(1代表已使用)
        boolean flag = false;
        for (int i = 0; i < 4; i++) {
            nums[i] = Integer.parseInt(number[i]); // 读取数字
        }

      
        int val = 0;
        boolean f =  dfs(nums, visit, 1, val);
        System.out.println(f);
    }

    //本题对数字选取顺序无要求  全排列
    static boolean dfs(int a[], boolean visit[], int nums, int val) {
        if (nums == 5 && val == 24) {
            return true;
        }
        if (nums == 5) return false;

        boolean flag = false;

        for (int i = 0; i < a.length; i++) {
            if (!visit[i]) {
                visit[i] = true;
                //首次递归放入 val = 0
                flag |= dfs(a, visit, nums + 1, val + a[i]);
                flag |= dfs(a, visit, nums + 1, val - a[i]);
                flag |= dfs(a, visit, nums + 1, val * a[i]);
                if (val % a[i] == 0) flag |= dfs(a, visit, nums + 1, val / a[i]);
                visit[i] = false;

                if (flag) return true;
            }
        }
        return false;
    }
}

给定入栈序列求出战序列

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
import java.util.LinkedList;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        LinkedList<Integer> in = new LinkedList<>();
        LinkedList<String> res =  new LinkedList<>();
        int n  = sc.nextInt();
        int arr[] = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
        dfs(arr, in, res, "", 0, 0);
        Collections.sort(res);
        for (String r : res) {
            System.out.println(r);
        }
    }

    //in入栈次数 out出栈次数
    static void dfs(int []a, LinkedList<Integer> s,  LinkedList<String> res,
                    String str, int in, int out) {
        //火车全部出栈了就 退出
        if (out == a.length) {
            res.add(str);
        }
        //如果当前栈内不为空 那就出栈
         if (!s.isEmpty()) {
            int temp = s.pop();
            dfs(a, s, res, str + temp + " ", in, out + 1);
            //恢复现场 当前火车恢复 看还有未入栈的火车没有
            s.push(temp);
        }
        //如果还有火车未入栈 那就入栈,没有就退出当前层
         if (in < a.length) {
            s.push(a[in]);
            dfs(a, s, res, str, in + 1, out);
             //恢复
            s.pop();
        }
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/795485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue如何设置网站标题和logo图标

目录 1、在根目录找到项目index.html文件 2、在index.html 的 title标签中修改名称为自己设计的标题 3、在index.html 的 title标签下的link标签中引入图标 ①格式为&#xff1a; ②注意&#xff1a; 1、在根目录找到项目index.html文件 2、在index.html 的 title标签中修改…

Visual Assist X Crack

Visual Assist X Crack Visual Assist X通过Visual Studio中的关键新功能和对现有功能的改进&#xff0c;大大缩短了应用程序开发时间&#xff0c;使您能够&#xff1a;Visual Assist提高了自动化程度&#xff0c;简化了导航&#xff0c;并在开发过程中显示重要信息。这些功能已…

WebDAV之π-Disk派盘+ WinSCP

WinSCP是一个免费的开源文件传输应用程序&#xff0c;它使用文件传输协议&#xff0c;安全外壳文件传输协议和安全复制协议来进行纯文件或安全文件传输。该应用程序旨在与Windows一起使用&#xff0c;并支持常见的Windows桌面功能&#xff0c;例如拖放文件&#xff0c;跳转列表…

Python web实战 | 使用 Django 搭建 Web 应用程序 【干货】

概要 从社交媒体到在线购物&#xff0c;从在线银行到在线医疗&#xff0c;Web 应用程序为人们提供了方便快捷的服务。Web 应用程序已经成为了人们日常生活中不可或缺的一部分。搭建一个高效、稳定、易用的 Web 应用程序并不是一件容易的事情。本文将介绍如何使用 Django 快速搭…

2_Apollo4BlueLite中断控制器NVIC

1.概述 Apollo4BlueLite 的中断控制器是采用 ARM Cortex-M4 内核&#xff0c;并集成了 NVIC&#xff08;Nested Vectored Interrupt Controller&#xff0c;嵌套向量中断控制器&#xff09;作为其中断控制器。 NVIC 是 ARM Cortex-M 系列处理器中常用的中断控制器&#xff0c…

Linux centos7.x系统将/home磁盘分配给/

1.解除挂载并删除/home卷 umount /home如果出现以下报错 &#xff1a; 可以使用以下命令查看哪些进程在占用 fuser -mv /home杀死这些进程就行 kill -9 进程号然后再执行umount /home就可以成功了 &#xff0c; 同时执行以下命令把逻辑卷删除了 lvremove /dev/centos/home…

腾讯云标准型S6/SA3/SR1/S5/SA2服务器CPU处理器大全

腾讯云服务器CVM标准型CPU处理器大全&#xff0c;包括标准型S6、SA3、SR1、S5、S5se、SA2、S4、SN3ne、S3、SA1、S2ne实例CPU处理器型号大全&#xff0c;标准型S6云服务器CPU采用Intel Ice Lake(2.7GHz/3.3GHz)&#xff0c;标准型S5采用Intel Xeon Cascade Lake 8255C/Intel Xe…

Linux C tcp/ip

服务端代码&#xff1a; #include <stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<string.h> #include<netinet/in.h> #include<arpa/inet.h> #include <unistd.h>/* socket bind listen accept send/receive *…

SpringBoot Redis 多数据源集成支持哨兵模式和Cluster集群模式

Redis 从入门到精通【应用篇】之SpringBoot Redis 多数据源集成支持哨兵模式Cluster集群模式、单机模式 文章目录 Redis 从入门到精通【应用篇】之SpringBoot Redis 多数据源集成支持哨兵模式Cluster集群模式、单机模式0.前言说明项目结构Pom 依赖 1. 配置1.1 通用配置&#xf…

二、SQL-6.DCL-1).用户管理

一、DCL介绍 Data Control Language 数据控制语言 用来管理数据库 用户、控制数据库的 访问权限。 二、语法 1、管理用户 管理用户在系统数据库mysql中的user表中创建、删除一个用户&#xff0c;需要Host&#xff08;主机名&#xff09;和User&#xff08;用户名&#xff0…

记一次安装nvm切换node.js版本实例详解

最后效果如下&#xff1a; 背景&#xff1a;由于我以前安装过node.js&#xff0c;后续想安装nvm将node.js管理起来。 问题&#xff1a;nvm-use命令行运行成功&#xff0c;但是nvm-list显示并没有成功。 原因&#xff1a;因为安装过node.js&#xff0c;所以原先的node.js不收n…

感谢CSDN发的证书

最近收到了CSDN发的电子证书&#xff0c;在此发文表示感谢&#xff01; 同时感谢一起关注我的粉丝和网友&#xff01; 下面是证书&#xff1a;

如何基于 Apache Doris 构建新一代日志分析平台|解决方案

作者&#xff1a;肖康&#xff0c;SelectDB 技术 副总裁 、Apache Doris Committer 日志数据是企业大数据体系中重要的组成部分之一&#xff0c;这些数据记录了网络设备、操作系统以及应用程序的详细历史行为&#xff0c;蕴含了丰富的信息价值&#xff0c;在可观测性、网络安全…

CTFSHOW web 信息收集

web入门的刷题 web1 教我们多看看源代码 web2 抓包 web3 抓包 web4 robots.txt robots.txt web5 phps源代码泄露 phps 就是php的源代码 用户无法访问 php 只可以通过phps来访问 web6 源代码备份 web7 git web8 svn web9 swp /index.php.swp web10 cookie web11 查域名…

[论文笔记] CLRerNet: Improving Confidence of Lane Detection with LaneIoU

Honda, Hiroto, and Yusuke Uchida. “CLRerNet: Improving Confidence of Lane Detection with LaneIoU.” arXiv preprint arXiv:2305.08366 (2023). 2023.05 出的一篇车道线检测的文章, 效果在CULane, CurveLanes SOTA 文章目录 简介LaneIoULineIoU存在问题为什么使用LaneIo…

部署 nagios 监控系统

Nagios NRPE 是监控软件 nagios 的一个扩展&#xff0c;它被用于被监控的服务器上&#xff0c;向 nagios 监控平台提供该服务器的一些本地的情况。例如&#xff0c;cpu 负载、内存使用、硬盘使用等等。NRPE 可以称为 nagios 的 for linux 客户端。 搭建 nagios 监控系统 安装…

MySQL数据表的高级操作

目录 一、克隆表&#xff0c;将数据表的数据记录生成到新的表中 方法1&#xff1a;先克隆表结构&#xff0c;再导入表数据。 方法2&#xff1a;创建新表的同时&#xff0c;导入旧表数据。 二、查看表结构的三种方法 三、清空表&#xff0c;删除表内的所有数据 方法一&…

1 Linux基础篇-课程内容介绍

1Linux基础篇-课程内容介绍 文章目录 1Linux基础篇-课程内容介绍1.1 Linux简介1.1 课程内容1.2 Linux的应用领域 学习视频来自于B站 【小白入门 通俗易懂】2021韩顺平 一周学会Linux。 1.1 Linux简介 Linux是与Windows齐名的操作系统&#xff0c; 学习目标&#xff0c;在工作…

计算机视觉:图像质量评价指标之 PSNR 和 SSIM

1. PSNR (Peak Signal-to-Noise Ratio) 峰值信噪比 由上可见&#xff0c;PSNR相对MSE多了一个峰值&#xff0c;MSE是绝对误差&#xff0c;再加上峰值是一个相对误差指标 一般地&#xff0c;针对 uint8 数据&#xff0c;最大像素值为 255,&#xff1b;针对浮点型数据&#xff…

配置IPv4 over IPv6隧道示例

IPv4 over IPv6隧道&#xff1a; 在IPv4 Internet向IPv6 Internet过渡后期&#xff0c;IPv6网络被大量部署后&#xff0c;而IPv4网络只是散布在世界各地的一些孤岛。利用隧道技术可以在IPv6网络上创建隧道&#xff0c;从而实现IPv4孤岛的互联&#xff0c;IPv4孤岛能通过IPv6公…