【2023华为od机考】算法题答案记录100分题

准备od机考中, c++答案和java都有

标括号(博客)代表是题目链接里给的答案, 大部分是自己写的, 比较喜欢打上注释, 帮助理解

我觉得c++还是简洁点, 不过有的题目就是为了考java的集合用法, 就用java更好

题目链接

华为OD机试真题2023(JAVA&JS)_华为机试真题_若博豆的博客-CSDN博客

1 猜字谜

c++代码(我写的)

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 20010;

string aa[N], bb[N];

int main()
{
    string a;//谜面
    string b;//谜底 在谜底中找谜面里的错误词
    
    getline(cin, a);
    getline(cin, b);
    
    string res;//每个单词
    int count = 0;
    for(int i = 0; i < a.length(); i ++ ) 
    {
        if(a[i] == ',') 
        {
            aa[count ++ ] = res;
            res = "";
        } 
        else res += a[i];
    } 
    aa[count] = res;//最后一个res也存进去 count不用加了
    int len_aa = count + 1;
    
    res = "";
    count = 0;
    for(int i = 0; i < b.length(); i ++ ) 
    {
        if(b[i] == ',') 
        {
            bb[count ++ ] = res;
            res = "";
        } 
        else res += b[i];
    } 
    bb[count] = res;//最后一个res也存进去 count不用加了
    int len_bb = count + 1;
    
    bool flag = false;//是否找到
    bool comma = false;//是否有逗号
    
    //然后两个字符串数组就是 aa 和 bb, 长度分别是len_aa, len_bb
    for(int i = 0; i < len_aa; i ++ ) {//循环aa字符串数组, 
        string str = aa[i];
        sort(str.begin(), str.end());
        str.erase(unique(str.begin(), str.end()), str.end()); //去掉重复元素
        for(int j = 0; j < len_bb; j ++ ) {
            string str2 = bb[j];
            sort(str2.begin(), str2.end());
            str2.erase(unique(str2.begin(), str2.end()), str2.end());
            
            if(str2 == str) {
                if(comma) cout << ',';
                cout << bb[j];
                flag = true;
                comma = true;
                break;
            }
        }
        if(flag == false) cout << "not found" << endl;
        flag = false;
    }
    
    return 0;
}

java代码(博客里的):

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] question=in.nextLine().split(",");
        String[] answer=in.nextLine().split(",");
        
        List<String> resList=new ArrayList<>();
        for(int i=0;i<question.length;i++){
            String q=question[i];
            boolean isFound=false;
            for(int j=0;j<answer.length;j++){
                String a=answer[j];
                if(change(q,a)){
                    resList.add(a);
                    isFound=true;
                }else if(dist(q,a)){
                    resList.add(a);
                    isFound=true;
                }
            }
            if(!isFound){
                resList.add("not found");
            }
        }
            String res= "";
            for(int i=0;i<resList.size();i++){
                res+=resList.get(i)+",";
            }
            System.out.println(res.substring(0,res.length()-1));
        }
    public static boolean dist(String question,String answer){
        List<Character> qList=new ArrayList<>();
        for(int i=0;i<question.length();i++){
            char c=question.charAt(i);
            if(!qList.contains(c)){
                qList.add(c);
            }
        }
        List<Character> aList=new ArrayList<>();
        for(int i=0;i<answer.length();i++){
            char c=answer.charAt(i);
            if(!aList.contains(c)){
                aList.add(c);
            }
        }
        if(qList.equals(aList)){
            return true;
        }
        return false;
        
    }
    public static boolean change(String question,String answer){
        String[] qStr=question.split("");
        Arrays.sort(qStr);
        String[] aStr=answer.split("");
        Arrays.sort(aStr);
        if(Arrays.equals(qStr,aStr)){
            return true;
        }
        return false;
    }
}

2 木板

题目链接: 

【满分】【华为OD机试真题2023 JAVA&JS】木板_若博豆的博客-CSDN博客

java代码(博客里的):

public class Main{
 
    public static void main(String[] args) {
 
        Scanner sc = new Scanner(System.in);
 
        int n = sc.nextInt();
        int m = sc.nextInt();
 
        int[] nums = new int[n];
        for(int i=0; i<n; i++){
            nums[i] = sc.nextInt();
        }
 
        Arrays.sort(nums);
 
        while (m>0){
            m--;    //木材一段一段的截
            for(int i=1; i<n; i++){
                if(nums[i] > nums[i-1]){
                    nums[i-1] ++;   //碰到比后面的短的就加一截
                    break;
                }
                if(i == n-1){
                    nums[i] ++; //所有木材一样长则在最后一根加一截
                }
            }
        }
 
        System.out.println(nums[0]);
    }
}

c++代码:

#include <iostream>
#include <algorithm>
 
using namespace std;
 
const int N = 100010;
 
int n, m;
int a[N];
 
int main()
{
    scanf("%d%d", &n, &m);
    
    int min = 0;
    
    for(int i = 0; i < n; i ++ ) 
        scanf("%d", &a[i]);
    
    sort(a , a + n);//从小到大排序
    
    while(m -- ) {
        for(int i = 1; i < n; i ++ ) {
            if(a[i] > a[i - 1])//如果比前一个长, 前一个+1
            {
                a[i - 1] ++ ;//
                break;
            }//否则 不加
            if(i == n - 1)//遍历到尾巴了, 就最后一节+1
            {
                a[i] ++ ;
            }
        }
        
    }
    
    cout << a[0] << endl;
    
    return 0;
}

3 查找重复代码

题目链接:

java(博客里的)

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();
        String str2 = sc.nextLine();
        String result = "";
        int start = 0;
        int end = 1;
        while(end <= str2.length()){
            String subStr = str2.substring(start,end);
            if (str1.contains(subStr)){
                result = subStr;
            }else {
                start++;
            }
            end++;
        }
        System.out.println(result);
    }
}

c++代码:

#include <iostream>
 
using namespace std;
 
int main()
{
    string a;//0-200 暴力枚举
    string b;
    getline(cin, a);
    getline(cin, b);
    
    int len1 = a.length();
    int len2 = b.length();
    if(len1 > len2) swap(a, b);//让a是短的
    
    string res = "";
    
    //双指针 [i,j] 判断 n * n = 10000
    for(int j = len1 - 1; j > 0; j -- )
    {
        for(int i = 0; i < j; i ++ )
        {
            string temp = a.substr(i, j - i + 1);
            if(b.find(temp) != -1) {
                if(temp.length() > res.length())
                res = temp;
            }
        }
    }
    
    cout << res << endl;
    
    return 0;
}

5 单词倒序

java代码(博客里的)

 
import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        String result = "";
        int start = 0;
        for (int i = 0; i< str.length(); i++) {
            char a = str.charAt(i);
            if (a==' ' || a=='?' || a=='.' || a==',') {
                if (i > start) {
                    StringBuilder word = new StringBuilder(str.substring(start, i));
                    result = result + word.reverse() + a;
                } else {
                    result = result + a;
                }
                start = i + 1;
            } else if (i == str.length() -1) {
                    StringBuilder word = new StringBuilder(str.substring(start, i + 1));
                    result = result + word.reverse();
                }
        }
        System.out.println(result);
    }
}

c++代码:

#include <iostream>
 
using namespace std;
 
int main()
{
    string a[100];
    int i = 0;
    while(cin >> a[i]) i ++;
    for(int j = 0; j < i; j ++ )
    {
        //取出字符串数组中的每个字符串a[i]
        string str = a[j];
        char temp = '\0';
        for(int k = str.length() - 1; k >= 0; k -- )
        {
            //反转后将字符串中的每个字符输出
            //如果是标点, 先不输出
            if(str[k] == ',' || str[k] == '.' || str[k] == '!') {
                temp = str[k];
            }
            else cout << str[k];
        }
        if(temp != '\0') cout << temp;
        cout << ' ';
        temp = '\0';
    }
    
    cout << endl;
    
    return 0;
}

6 打印文件

java代码(博客里的)

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        List<List<File>> m = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            m.add(new ArrayList<>());
        }
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int flag = 0;
        for (int i = 0; i <= n; i++) {
            String s = in.nextLine();
            String[] s1 = s.split(" ");
            String type = s1[0];
 
            if ("IN".equals(type)) {
                int p = Integer.parseInt(s1[1]);
                int num = Integer.parseInt(s1[2]);
                flag++;
                File file = new File(flag, num);
                List<File> files = m.get(p - 1);
                files.add(file);
            } else if ("OUT".equals(type)) {
                int p = Integer.parseInt(s1[1]);
                List<File> files = m.get(p - 1);
                if (files != null && files.size() > 0) {
                    files.sort((a, b) -> {
                        return b.getWeight() - a.getWeight();
                    });
                    File file = files.get(0);
                    System.out.println(file.getIndex());
                    files.remove(0);
                } else {
                    System.out.println("NULL");
                }
            }
 
        }
 
 
    }
}
 
class File {
    private int index;
    private int weight;
 
    public File(int index, int weight) {
        this.index = index;
        this.weight = weight;
    }
 
    public int getIndex() {
        return index;
    }
 
    public void setIndex(int index) {
        this.index = index;
    }
 
    public int getWeight() {
        return weight;
    }
 
    public void setWeight(int weight) {
        this.weight = weight;
    }
}

c++代码: 

#include <iostream>
#include <algorithm>
 
#define x first
#define y second
 
using namespace std;
 
const int N = 1010;
typedef pair<int, pair<int, int>> PII;
 
int m;
vector<PII> alls;
 
int main()
{
    scanf("%d", &m);
    int count = 1;//文件的编号
    
    while(m -- ) {
        string op;
        
        cin >> op;
        int p, n;
        bool flag = false;
        
        if(op == "IN") 
        {
            scanf("%d%d", &p, &n);//打印机编号p, 优先级n
            alls.push_back({n, {count, p}});
            count ++ ;
            
            //sort(alls.rbegin(), alls.rend());//按照n排序
            sort(alls.rbegin(), alls.rend(), [](const PII &a, const PII &b){
                return a.x < b.x; // 先按照优先级n降序, 再按照插入顺序count升序
            });
            
            // for(auto e : alls) 
            // {
            //     cout << e.x << ' '<< e.y.x << ' ' << e.y.y << endl;
            // } cout << endl;
        } 
        else if(op == "OUT")
        {
            scanf("%d", &p);
            
            int len = alls.size();
            //遍历输出结果
            for(int i = 0; i < len; i ++ ) 
            {
                //如果有结果 输出结果, 在数组中删除该数 flag=true, 退出循环
                if(alls[i].y.y == p) 
                {
                    cout << alls[i].y.x << endl;
                    auto iter = alls.erase(alls.begin() + i);//删除元素
 
                    flag = true;
                    break;
                } 
            }
            //如果遍历完都没有结果, flag还是false 输出NULL
            if(flag == false) cout << "NULL" << endl;
            flag = false;
        }
    }
    return 0;
}

7 对称字符串

c++代码, 不过这个回溯会爆内存 报memory limit exceeded 或者 time limit exceeded

#include <iostream>

using namespace std;

const int N = 100010;

int t, n, k;

string solve(int x) {//每次就是把前一个的字符串取反 + 原字符串
    if(x == 1) return "R";//1输出R
    
    string str = solve(x - 1);
    
    string res = "";
    for(int i = 0; i < str.length(); i ++ ) {
        if(str[i] == 'R') res += 'B';
        else if(str[i] == 'B') res += 'R';
    }
    
    return res + str; //翻转结果 + 原字符串
}

int main()
{
    scanf("%d", &t);
    
    while(t -- ) {
        scanf("%d%d", &n, &k);
        string ans = solve(n);//只能在25以内, 否则memory limit exceeded
        if(ans[k] == 'R') cout << "red" << endl;
        else cout << "blue" << endl;
    }
    
    return 0;
}

 c++ 找规律写法: 这个是扒的博客java解法

#include <iostream>
#include <cmath>
#include <algorithm>

typedef long long ll;
using namespace std;

int t, n, k;//n是第几个字符串, k是字符的位置

int solve(ll len, ll k, int rev) //len是字符串的长度, k是位置, rev是翻转次数
{
    if(len == 1) return rev;//回溯到最底层 就返回现在的rev就是翻转的次数
    
    ll half = len / 2;//长度的一半
    if(k < half) { //k在前半部分, 是反转后的部分
        rev ++ ;//翻转次数++
        return solve(half, k, rev);
    } else {//后半部分
        return solve(half, k - half, rev);
    }
}

int main()
{
    scanf("%d", &t);
    
    while(t -- ) {
        scanf("%d%d", &n, &k);
        //长度
        ll len = (ll)pow(2, n - 1);
        //cout << len << endl;
        
        int ans = solve(len, k, 0);//传入长度, 位置, 求该位置的翻转次数
        //原字符是R 翻转偶数次就是R 翻转奇数次就是B
        if(ans % 2) cout << "blue" << endl;//奇数次
        else cout << "red" << endl;//偶数次
        
    }
    
    return 0;
}

java代码(博客)

public class Main{
 
    public static void main(String[] args) {
 
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
 
        for(int i=0; i<T; i++){
            int n = sc.nextInt();
            long k = sc.nextLong();
 
            long charNum = (long) Math.pow(2, n - 1);       //第n行的总字符个数
            int re = doProcess(charNum, k, 0);
            if (re % 2 == 0) {
                System.out.println("red");      //翻转次数为2的倍数
            } else {
                System.out.println("blue");
            }
        }
 
    }
 
    /**
     * 翻转次数
     * @param count     总字符的个数
     * @param cur       字符的索引
     * @param reverse       翻转次数
     * @return
     */
    public static int doProcess(long count, long cur, int reverse){
 
        if (count == 1) {
            return reverse;
        }
        long half = count / 2;
        if (cur < half) {    //小于半数说明是经过翻转的部分
            reverse ++;
            return doProcess(half, cur, reverse);
        } else {
            return doProcess(half, cur - half, reverse);
        }
    }
 
}

8 分界线

爷的c++代码, 纯打暴力

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 110;

string aa[N], bb[N];

int main()
{
    string a;//报纸内容
    string b;//是否可以拼成的 匿名信
    
    getline(cin, a);
    getline(cin, b);
    
    string res = "";
    int j = 0;
    for(int i = 0; i < a.length(); i ++ ) //100 * 104 = 100400
    {
        if(a[i] == ' ') {
            aa[j ++ ] = res;
            res = "";
        } else res += a[i];
    } aa[j ++ ] = res;
    //存进去了aa[N] 报文的字符串数组
    int len_a = j;
    
    res = "";
    j = 0;
    for(int i = 0; i < b.length(); i ++ ) //100400
    {
        if(b[i] == ' ') {
            bb[j ++ ] = res;
            res = "";
        } else res += b[i];
    } bb[j ++ ] = res;
    //存进去了bb[N] 报文的字符串数组
    int len_b = j;
    
    int count = 0;
    for(int i = 0; i < len_b; i ++ ) {//枚举每个匿名信单词
        string ano = bb[i];
        sort(ano.begin(), ano.end());
        for(int j = 0; j < len_a; j ++ ) {//枚举原报文遍历单词
            string news = aa[j];
            sort(news.begin(), news.end());
            if(ano == news) {
                count ++ ;
                break;//结束报文的遍历
            } 
        }
    }
    if(count == len_b) cout << "true" << endl;
    else cout << "false" << endl;
    
    return 0;
}

java(博客里的)

import java.util.Arrays;
import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc  = new Scanner(System.in);
        String newsapper = sc.nextLine();
        String anonymousLetter = sc.nextLine();
        String[] newsapperArr = newsapper.split(" ");
        String[] anonymousLetterArr = anonymousLetter.split(" ");
        for (int i = 0; i < anonymousLetterArr.length; i++) {
            String ii = anonymousLetterArr[i];
            char[] ic = ii.toCharArray();
            Arrays.sort(ic);
            boolean flag = false;
            for (int j = 0; j < newsapperArr.length; j++) {
                String jj = newsapperArr[j];
                char[] jc = jj.toCharArray();
                Arrays.sort(jc);
                if (Arrays.equals(ic, jc)){
                    flag = true;
                    break;
                }
            }
            if (!flag){
                System.out.println(false);
                System.exit(0);
            }
        }
        System.out.println(true);
    }
}

9 关联端口组合并

string数组转成int数组的方法: 

String数组转int数组_躺平的菜鸟啊的博客-CSDN博客

不需要像c++那样遍历了哈哈哈,  java也不错嘛

java代码(博客里的思路) 我打了备注, 改动了一点:

import java.util.*;

public class Main{
    public static void main(String[] args){
        
        Scanner myScanner = new Scanner(System.in);
        
        //二维数组, 外层用list保存, 内层用set集合保存, set集合有去重和排序的功能,
        //每输入一个组合, 对list进行遍历, 找出其中有两个并集的集合进行合并
        
        int m = myScanner.nextInt();
        
        if(m > 10) System.out.println("[[]]");
        else {
            List<Set<Integer>> list = new ArrayList<>();
            //myScanner.nextLine();//读取行
            
            //循环
            for(int i = 0; i < m; i ++ ) {
                String[] strings = myScanner.nextLine().split(",");//读取行 分成zi字符串数组strings
                int[] nums = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();//转换成字符串数组nums
                
                Set<Integer> set = new TreeSet<>();
                
                if(nums.length == 1 ) {//只有一个元素, 直接添加
                    set.add(nums[0]);
                    list.add(set);//加入list
                } else {
                    for(int num : nums) {
                        set.add(num);//数字加到set集合中
                    }
                    list.add(set);//这个新的set加到list, 默认加到最后
                    merge(set, list, list.size() - 1 );//看是否需要合并set和list内的set
                }
            }
            
            System.out.println(list);//输出结果
        }
        
        
    }
    
    public static void merge(Set<Integer> set, List<Set<Integer>> list, int index) {
        for(int i = 0; i < list.size(); i ++ ) {//遍历list中的每个set 
            if(i == index) continue;//如果是相同 就不继续了
        
            Set<Integer> setIdx = list.get(i);//当前索引的set集合
            
            Set<Integer> setTemp = new TreeSet<>();
            setTemp.addAll(set);//临时集合 保存交集 
            
            setTemp.retainAll(setIdx);//待判断的set和当前的setIdx的交集, 返回交集
            
            if(setTemp.size() >= 2) {//当交集>=2 则需要合并
            
                set.addAll(setIdx); //把新传入的set与setIdx合并
                
                list.remove(i);//两个都移除后
                list.remove(index);
                
                int st = i < index ? i : index;//存靠前的下标
                list.add(st, set);//加上并集set 在st位置 
                
                merge(set, list, st);//新建的组合再进行判断合并, 因为合并之后
            }
        }
    }
}

10 货币单位换算

c++代码, 按照博客思路写的

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

int n;

double solve(string str, char c) {
    
    double res;
    for(int i = 0; i < str.length(); i ++ ) {
        res *= 10;
        res += str[i] - '0';
    }
    
    if(c == 'C') res *= 100;
    else if(c == 'J') res *= (double) 10000 / 1825;
    else if(c == 'H') res *= (double) 10000 / 123;
    else if(c == 'E') res *= (double) 10000 / 14;
    else if(c == 'G') res *= (double) 10000 / 12;
            
    else if(c == 'f') res *= 1;
    else if(c == 's') res *= (double) 100 / 1825;
    else if(c == 'c') res *= (double) 100 / 123;
    else if(c == 'e') res *= (double) 100 / 14;
    else if(c == 'p') res *= (double) 100 / 12;
    
    return res;
}

int main(){
    
    scanf("%d", &n);
    double res = 0;
    
    while(n -- ) {
        string str;
        cin >> str;
        
        string tmp;
        
        for(int i = 0; i < str.length(); i ++ ) {
            char c = str[i];
            if(c >= '0' && c <= '9') tmp += str[i];
            else {
                res += solve(tmp, c);
                
                i += 2;
                if(c == 'c') i += 2;
                else if(c == 'e') i += 8;
                else if(c == 'p') i += 2;
                
                tmp = "";//重来
            }
        }
    }
    
    cout << floor(res) << endl;
    return 0;
}

java代码(博客中的)

import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        double money = 0.0;
        int count = Integer.parseInt(sc.nextLine());
        for (int i = 0; i < count; i++) {
            String line = sc.nextLine();
            String[] split = line.split("\\d");
            for (String type : split) {
                if(!type.isEmpty()){
                    String num = line.substring(0, line.indexOf(type));
                    money += getCny(type, Double.parseDouble(num));
                    line = line.substring(line.indexOf(type) + type.length());
                }
            }
        }
        System.out.println(Math.round(Math.floor(money)));
    }
 
    private static double getCny(String type, double num) {
        switch (type) {
            case "CNY":
                return num * 100;
            case "fen":
                return num;
            case "JPY":
                return num / 1825 * 10000;
            case "sen":
                return num / 1825 * 100;
            case "HKD":
                return num / 123 * 10000;
            case "cents":
                return num / 123 * 100;
            case "EUR":
                return num / 14 * 10000;
            case "eurocents":
                return num / 14 * 100;
            case "GBP":
                return num / 12 * 10000;
            case "pence":
                return num / 12 * 100;
        }
        return 0;
    }
 
}

11 获得完美走位

java代码(博客中的, 我打了备注)

import java.util.*;
 
public class Main{
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
 
        int strLen = str.length();
        int count = strLen / 4;
        Map<Character, Integer> map = new HashMap<>();
        
        //把字符串中所有的字符存到map中, k-v表示字符-个数
        for(int i = 0; i < strLen; i++)
        {
            char c = str.charAt(i);
            if(map.containsKey(c)) map.put( c, map.get(c) + 1);//保存k-v 字符-个数+1
            else map.put( c, 1 - count);//字符-需要的个数(用负数表示, 最后才能归0)
        }//比如AASW 就是 [A,1] [S,0] [W,0]  
 
        int min = str.length();
        
        for (int i = 0; i < strLen; i++) {
            HashMap<Character, Integer> copy = new HashMap<>(map);
            int res = 0;
            
            if (copy.get(str.charAt(i)) > 0) //如果某个方向多走了
            {
                for (int j = i; j < str.length(); j++) //往后遍历其他的
                {
                    char c = str.charAt(j);
                    copy.put(c, copy.get(c) - 1);//把他变换一下
                    res ++ ;//答案++
                    if (isZero(copy)) break;//判断是否都是0
                }
            }
            if (isZero(copy)) res = Math.min(min, res);
        }
 
        System.out.println(res);
    }
 
    private static boolean isZero(HashMap<Character, Integer> copy) {
        Collection<Integer> values = copy.values();
        for (Integer value : values) {
            if (value > 0) return false;
        }
        return true;
    }
}

12 简单的自动曝光

忽然发现我自己做的题, 不一定会满分哈哈 因为都只测了一两个用例

c++代码: 这个很简单

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

const int N = 110;

int a[N];

int main(){
    
    int sum = 0;
    
    int i = 0;
    while(cin >> a[i]) {
        sum += a[i]; 
        i ++ ;
    }
    
    double res = (double)(512 - sum) / 4;
    
    cout << floor(res) << endl;//向下取整 1 2
    
    return 0;
}

参考一下java的满分答案, 博客里面的: 

import java.util.*;
import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;
import java.util.stream.Stream;
 
public class Main{
 
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
 
        String[] strings = in.nextLine().split(" ");
        int[] nums = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();
 
        solution(nums);
    }
 
    public static void solution(int[] list) {
        int ans = 0;
        int t = Integer.MAX_VALUE;
        for (int i = -127; i < 255; ++i) {
            int sum = 0;
            for (int j = 0; j < list.length; ++j) {
                int tmp = i + list[j];
                if (tmp < 0) {
                    tmp = 0;
                } else if (tmp > 255) {
                    tmp = 255;
                }
                sum += tmp;
            }
            if (t > Math.abs(128 * list.length - sum)) {
                ans = i;
                t = Math.abs(128 * list.length - sum);
            }
        }
        System.out.println(ans);
    }
 
}

13 日志采集系统

c++ 代码, 我觉得我写的很牛哈哈哈

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

const int N = 1010;//最多1000个 每个里面100条

int a[N], s[N], m[N];//

int main(){
    
    int i = 1;
    while(cin >> a[i]) {
        
        s[i] = s[i - 1] + a[i];//前缀和
        m[i] = s[i - 1] + s[i];//要减去的
        //cout << s[i] << ' ' <<m[i] << endl;
        i ++ ;
    }
    int n = i;//总采集次数
    
    int res = 0;
    int score = 0;
    for(int i = 1; i <= n; i ++ ) 
    {
        score = min(100, s[i]) - m[i - 1];
        
        res = max(res, score);
        
        if(s[i] >= 100) break;
    }
    
    cout << res <<endl;
    return 0;
}

java代码:

就不放了 没我写得好

14 数组的中心位置

c++ 简洁优雅, 不过可能会爆int 需要优化一下

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

const int N = 1034;//最多1024个

int a[N], s[N];

int main(){
    
    int i = 1;
    s[0] = 1;
    while(cin >> a[i]) {
        s[i] = s[i - 1] * a[i];
        i ++ ;
    }
    int n = i - 1;
    
    for(int j = 1; j <= n; j ++ ) {
        if(s[j] * s[j + 1] == s[n]) {
            cout << j << endl;
            return 0;
        }
    }
        
    cout << "-1" << endl;    
    return 0;
}

优化:

看一下java解法 博客写的, 没动过:

public class Main{
 
    public static void main(String[] args) {
 
        Scanner sc = new Scanner(System.in);
        String[] strings = sc.nextLine().split(" ");
        int len = strings.length;
        int[] nums = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();
 
        //题目说:数组第一个元素的左侧积为1,最后一个元素的右侧积为1
        int left=1, right=1;
        for(int num : nums){
            right = right * num;    //数组的总乘积
        }
 
        boolean flag =false;
        for(int i=0; i<len; i++){
            if(i!=0){
                left = left * nums[i-1];    //左侧积做乘法
            }
            right = right / nums[i];    //右侧积做除法
            if(left == right){
                System.out.print(i);
                flag = true;
                break;
            }
        }
        if(!flag){
            System.out.println(-1);
        }
    }
 
}

15 通信误码

java代码: 按照博客思路打的

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        int n = sc.nextInt();
        
        int[] nums = new int[n];
        
        for(int i = 0; i < n; i ++ ) {
            nums[i] = sc.nextInt();
        }
        
        Map<Integer, Integer> map = new HashMap<>();//存k-v 误码-误码频率
        int max = 0;//数字出现的最大次数
        
        for(int i = 0; i < n; i ++ ) {
            int count = map.getOrDefault(nums[i], 0) + 1;//当前数字出现次数再加上1次
            max = Math.max(max, count);//取最大值
            map.put(nums[i], count);//存进map
        }
        
        Set<Integer> set = new HashSet<>();//存最高误码的集合
        for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
            if(entry.getValue() == max) {
                set.add(entry.getKey());//加入频率最高的数字
            }
        }
        
        int res = n;
        for(Integer integer : set) {//双指针 取出某个max值, 
            int l = 0, r = n - 1;
            while(nums[l] != integer) l ++ ;//当两个指针都是max值的时候才停下
            while(nums[r] != integer) r -- ;
            if(l <= r) res = Math.min(res, r - l + 1);//max取结果
        }
        
        System.out.println(res);
    }
}

getOrDefault方法: 

格式:
Map.getOrDefault(key,默认值);

Map中会存储一一对应的key和value。
如果 在Map中存在key,则返回key所对应的的value。
如果 在Map中不存在key,则返回默认值。

entrySet()

Java中Map的 entrySet() 详解以及用法(四种遍历map的方式)-CSDN博客

【java笔记】java中的Map.Entry和Map.entrySet()方法的使用_map.entry<integer,integer> entry:map.entryset()_棉花糖灬的博客-CSDN博客

Map中采用Entry内部类来表示一个映射项,映射项包含Key和Value (我们总说键值对键值对, 每一个键值对也就是一个Entry)
Map.Entry里面包含getKey()和getValue()方法

entrySet是java中 键-值对的集合,Set里面的类型是Map.Entry,一般可以通过map.entrySet()得到。

  • entrySet实现了Set接口,里面存放的是键值对。一个K对应一个V。

即通过getKey()得到K,getValue得到V。

这种遍历方法比较快: 

Map.Entry<Integer, Integer> entry : map.entrySet()

16 网上商城优惠

【华为OD机试真题2023 JAVA】网上商城优惠活动(一)_接口测试主要测哪些方面_若博豆的博客-CSDN博客z

这题绕糊涂了 , 没写对, 有空重新弄一下

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

int mj;
int dz;
int wmk;

int n;

double manjian(int money) {
    int a = money / 100;//可以使用的张数
    int count = a > mj ? mj : a;
    double res = (double) (money - count * 10) ;
    return res;
}

double wumenk(int money) {
    int a = money / 5;//可以使用的张数
    int count = a > wmk ? wmk : a;
    double res = (double) (money - count * 5) ;
    return res;
}

int main()
{
    scanf("%d%d%d", &mj, &dz, &wmk);
    scanf("%d", &n);
    
    int res;
    
    while(n -- ) {
        
        int money;
        scanf("%d", &money);//账单金额 操作前
        int res = 2e9;
        int tmp = 2e9;
        //C32 6中情况 打折只能用一次, 其他的无使用限制
        
        //先满减后打折
        if(mj > 0 && dz > 0) {
            tmp = manjian(money);
            tmp = floor((double)tmp * 0.92);
        } 
        res = min(res, tmp);
        
        //先满减后无门槛
        if(mj > 0 && wmk > 0) {
            tmp = manjian(money);
            tmp = wumenk(tmp);
        }
        res = min(res, tmp);
        
        //先打折后满减
        if(dz > 0 && mj > 0) {
            tmp = floor(money * 0.92);
            tmp = manjian(tmp);
        }
        res = min(res, tmp);
        
        //先打折后无门槛
        if(dz > 0 && wmk > 0) {
            tmp = floor((double)tmp * 0.92);
            tmp = wumenk(tmp);
        }
        res = min(res, tmp);
        
        //先无门槛后满减
        if(mj > 0 && wmk > 0) {
            tmp = wumenk(tmp);
            tmp = manjian(money);
        }
        res = min(res, tmp);
        
        //先无门槛后打折
        if(dz > 0 && wmk > 0) {
            tmp = wumenk(tmp);
            tmp = floor((double)tmp * 0.92);
        }
        res = min(res, tmp);
        
        
        cout << res << endl;
    }
    return 0;
}

java博客代码

import java.util.Scanner;
 
public class Main{
 
    public static int manjian;
    public static int dazhe;
    public static int wumenkan;
    //券的最小使用量
    public static int mincountQuan;
    //最少价格
    public static int minCount;
 
    public static void main(String[] args) {
 
        Scanner sc = new Scanner(System.in);
 
        manjian = sc.nextInt();
        dazhe = sc.nextInt();
        wumenkan = sc.nextInt();
 
        int n = sc.nextInt();
 
        for(int i=0; i<n; i++){
 
            double money = sc.nextInt();
 
            //首先使用满减的张数
            int quanMJ = money/100 > manjian ? manjian : (int) (money / 100);
 
            //使用无门槛的券的张数
            int quanWMK;
            //券的最小使用量
            mincountQuan = Integer.MAX_VALUE;
            //最少价格
            minCount = Integer.MAX_VALUE;
 
            if(dazhe > 0){  //有打折券的情况
 
                //先满减后打折
                int MJafterDZ = (int) Math.floor(Manjian(money) * 0.92);
                flush( MJafterDZ, quanMJ + 1);
 
                //先打折后满减
                int DZafterMJ = (int) Math.floor(Manjian(money * 0.92));
                //先打折后满减的满减券
                int quanDZafterMJ = (int) (money * 0.92 / 100 > manjian ? manjian : money * 0.92 / 100);
                flush( DZafterMJ, quanDZafterMJ + 1);
 
                //先打折后无门槛
                double dazhe = money * 0.92;
                //无门槛需要的张数
                quanWMK = wumenkan(dazhe);
                int dazheWMK;
                if(dazhe <= quanWMK * 5){
                    //打折后的价格小于等于无门槛的全部价格(可以0元购)
                    dazheWMK = 0;
                }else {
                    dazheWMK = (int) Math.floor(dazhe - quanWMK * 5);
                }
                flush( dazheWMK, quanWMK + 1);
 
                //先无门槛后打折
                int wmkDZ;
                //无门槛需要的张数
                quanWMK = wumenkan(money);
                if(money <= quanWMK * 5 ){
                    //价格小于等于无门槛的全部价格(可以0元购)
                    flush( 0, quanWMK);
                }else {
                    wmkDZ = (int) Math.floor((money - quanWMK * 5) * 0.92);
                    flush( wmkDZ, quanWMK + 1);
                }
            }
 
            //先满减后无门槛
            int mjWMK;
            double manjian= Manjian(money);
            //无门槛需要的张数
            quanWMK =  wumenkan(manjian);
            if(manjian <= quanWMK * 5){
                //满减后的价格小于等于无门槛的全部价格(可以0元购)
                mjWMK = 0;
            }else {
                mjWMK = (int) Math.floor(manjian - quanWMK * 5);
            }
            flush( mjWMK, quanWMK + quanMJ);
 
            System.out.println(minCount + " " + mincountQuan);
 
        }
    }
 
    /**
     * 刷新最少价格和最少使用券
     * @param count
     * @param quanCount
     */
    public static void flush(int count, int quanCount){
        if(count < minCount){
            minCount = count;
            mincountQuan = quanCount;
        }else if(count == minCount){
            mincountQuan = Math.min( quanCount, mincountQuan);
        }
    }
 
    /**
     * 求出需要无门槛优惠券的张数
     * @param money
     * @return
     */
    public static int wumenkan(double money){
 
        for(int i=1; i<=wumenkan; i++){
            if(money <= 5 * i) {
                return i;
            }
        }
 
        return wumenkan;
    }
 
    /**
     * 满减后的价格
     * @param money
     * @return
     */
    public static double Manjian(double money){
 
        if(money/100 >= manjian){
            return money - manjian*10;
        }else {
            return money - ((int) money/100)*10;
        }
    }
 
}

17 开心消消乐

java代码

感觉这个没有回溯啊 就是找到第一个点来计算的.. 有空看吧 先记住了

import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        int row = scanner.nextInt();
        int column = scanner.nextInt();
        
        int[][] numbers = new int[row][column];
        
        scanner.nextLine();
        
        for (int i = 0; i < row; i++) {//每行
            for (int j = 0; j < column; j++) {
                numbers[i][j] = scanner.nextInt();
            }
        }
 
        int count = 0;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                if (numbers[i][j] == 1) {//如果该点值为1 点击一下, 再继续循环其他的点
                    turnZero(numbers, row, column, i, j);
                    count++;
                }
            }
        }
 
        System.out.println(count);
    }
 
    private static void turnZero(int[][] numbers, int row, int col, int x, int y) {
        numbers[x][y] = 0;//点击为0
        for (int i = x - 1; i <= x + 1; i ++ ) {
            for (int j = y - 1; j <= y + 1; j ++ ) {//遍历相邻的8个点
                if (i >= 0 && i < row && j >= 0 && j < col && numbers[i][j] == 1) {//如果是1
                    turnZero(numbers, row, col, i, j);//就自动变为0
                }
            }
        }
    }
    
    
}

18 获取最大软件版本号

compareTo 复习一下

java中compareTo方法的使用_compareto在java中的用法_高某123的博客-CSDN博客

 java代码: 

import java.util.*;
 
public class Main {
 
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        String a = scanner.nextLine();
        String b = scanner.nextLine();
        
        
        String[] strs1 = a.split("\\.");//1.5.1-A 分成 1 5 1-A
        String[] strs2 = b.split("\\.");
        
        //比较主次版本 1.3.11-S2 1.05.1 中的 1 3 和 1 05 挨个遍历这两个字符
        for(int i = 0; i < 2; i ++ ) {
            int va = Integer.valueOf(strs1[i]);
            int vb = Integer.valueOf(strs2[i]);
            
            if(va != vb) {//继续遍历
                System.out.println(va > vb ? a : b);
                return;
            }
        }
        
        //增量版本可能不存在 如 直接是 1.5
        //比较增量版本 和里程碑版本
        if(strs1.length > 2 && strs2.length > 2 ) {//两个版本长度都 > 2
            //有增量版本 就在strs[2]位置
            String[] s1 = strs1[2].split("-"); //分成 1 A
            String[] s2 = strs2[2].split("-");
            
            int va = Integer.valueOf(s1[0]);
            int vb = Integer.valueOf(s2[0]);
            
            if(va != vb) {
                System.out.println(va > vb ? va : vb);
                return;
            }
            //增量版本也相同 如果都有里程碑版本
            if(s1.length == 2 && s2.length == 2) {
                //字典序排序 compareTo
                System.out.println(s1[1].compareTo(s2[1]) >= 0 ? a : b);
            } else {
                System.out.println(s2.length >= s2.length ? a : b);
            }
            
        } else {
            System.out.println(strs1.length >= strs2.length ? a : b);
        }
        
    }
    
}

19 寻找链表的中间节点

输入:

00100 4
00000 4 -1
00100 1 12309
33218 3 00000
12309 2 33218

输出: 3

输入:

10000 3
76892 7 12309
12309 5 -1
10000 1 76892

输出: 7

java代码: 博客里的 我打了备注

import java.util.*;
 
public class Main {
    
    public static class Node{
        String data;
        String next;
        public Node(String data, String next) {
            this.data = data;
            this.next = next;
        }
    }
 
    public static void main(String[] args) {
        //保存 地址 - 节点
        Map<String, Node> map = new HashMap<>();
        Scanner sc = new Scanner(System.in);
        
        //初始化元信息
        String[] mate = sc.nextLine().split(" "); //mate[0] 是 地址 mate[1] 是个数
        
        for(int i = 0; i < Integer.parseInt(mate[1]); i ++ ) {
            String[] info = sc.nextLine().split(" ");//每一行的地址 value next
            map.put(info[0], new Node(info[1], info[2]));
        }
        
        //通过list保存有效数据和记录数据链长度
        List<String> res = new LinkedList<>();//保存结果 list是有序的
        String address = mate[0];//起始地址是第一个
        
        while(true) {
            if(map.containsKey(address) == false)  break;
            //不包含起始地址, 链表为空; 或者找不到下一个地址, 链表结束
            
            Node node = map.get(address);//get(Key) 得到的v就是 Node
            res.add(node.data);//链表保存数据
            address = node.next;//address记录下一个node
        }
        
        //返回中间位置的值
        int idx = res.size() / 2;
        System.out.println(res.get(idx));
        
        
    }
    
}

20 最小的调整次数

输入:

3
head add 1
remove 
tail add 2
head add 3
remove 
remove

输出: 1

java代码

import java.util.*;
 
public class Main {
 
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.nextLine());//读取数据范围
        
        int cnt = 0;//变幻的次数
        int left = 0;//剩下待移除的数字
        boolean flag = false;//是否需要逆转
        
        //2n 行
        for(int i = 0; i < 2 * n; i ++ ) {
            
            //读取一行 head add 1 或者 remove
            String[] str = sc.nextLine().split(" ");
        
            if(str.length == 3 ) {//add操作
            
                if(left != 0) {//有数字的情况下
                
                    //如果是head, 就要调整一次顺序
                    if(str[0].equals("head") && !flag ) { //不需要调整 
                        flag = true;//标记需要调整
                    }
                    //如果是tail, 不用管, 直接添加
                }
                
                //如果left==0, 不管头和尾都直接添加
                left ++ ;//数字添加
            }
            
            if(str.length == 1) {//移除操作
                left -- ;//数字减少
                cnt += flag ? 1 : 0;//是不是需要调整, 需要的话结果+1
                flag = false;//调整完结束
            }
            
         }
         
         System.out.println(cnt);
    }
}

这个题目的意思是 一次调整可以调整所有的数, 所以一直等待一个head插入就可以计数了

21 字符串解密

java代码 自己打了备注

import java.util.*;

public class Main {
    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        
        String s1 = sc.nextLine();
        String s2 = sc.nextLine();
        
        //处理字符串2
        HashSet<String> set = new HashSet<>();
        for(char c : s2.toCharArray()) {//把字符串2变成字符数组 遍历每个字符
            set.add(c + "");//把每个字符都存到set中 set是自动去重的 
        }
        
        //处理字符串1
        String sub = "123456789abcdef";
        //去掉0-9 a-f
        int index = 0;//起始点
        ArrayList<String> list = new ArrayList<>();//保存删除0-9 a-f后的 字符串数组
            //保存筛选后的字符串
        for(int i = 0; i < s1.length(); i ++ ) {
            
            if(sub.contains(s1.charAt(i) + "")) {//遍历到0-9 a-f时, 保存当前字符串
                list.add(s1.substring(index, i));//substring(1,1)是空, 所以不保存
                index = i + 1;
            } else {
                if(i == s1.length() - 1) { //遍历到结尾的时候
                    list.add(s1.substring(index));
                }
            }
            
        }
        
        String res = "";
        for(int i = 0; i < list.size(); i ++) {//枚举i 获得每个子字符串
            
            String cs = list.get(i);//list里面每个子字符串
            
            
            if(cs.length > 0) {
                
                //hashset会自动去重, 获得的长度就是去重后的
                HashSet<String> cset = new HashSet<>();
                for(int j = 0; j < cs.length(); j++ ) {
                    cset.add(cs.charAt(j) + "" );
                }
                int len = cset.size();//去重后 每个子串的长度
                
                //如果这个子串满足题目要求的条件:  < 字符串2的长度
                if (len <= set.size()) {
                    //就把结果字符串去重 
                    HashSet<String> sset = new HashSet<>();
                    for (int j = 0; j < res.length(); j++) {
                        sset.add(res.charAt(j) + "");
                    }
                    int slen = sset.size();
                    
                    //如果子串长度 > 结果串长度, 更新结果
                    if (len > slen) {
                        res = cs;
                    } else if (len == slen && cs.compareTo(res) > 0) {//字典序
                        res = cs;//如果子串长度相同, 字典序更大 也更新结果
                    }

                }
                
                
 
            }
 
        }
        
        
        if (res.length() > 0) {
            System.out.println(res);
        } else {
            System.out.println("Not Found");
        }
         
        
    }
 
}

22 投篮大赛

java代码

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        
        String[] nums = s.split(" ");
        
        List<Integer> list = new ArrayList<>();
        
        int res = 0;
        for(int i = 0; i < nums.length; i ++ ) {//遍历每个串
            
            if(nums[i].equals("+")) {
                
                int j = list.size();
                if(list.size() < 2) {//需要集合 >= 2 才能+
                    System.out.println("-1");
                    return;
                }
                
                int grade = list.get(j - 1) + list.get(j - 2);//倒数第一个和倒数第二个
                list.add(grade);
                
            } else if (nums[i].equals("D")) {
                
                int j = list.size();
                if(list.size() < 1) {//需要集合 >= 1 需要前面有一个数字
                    System.out.println("-1");
                    return;
                }
                
                int grade = list.get(j - 1) * 2;
                list.add(grade);
                
            } else if(nums[i].equals("C") ) {
                
                if(list.size() < 1 ) {//需要集合 >= 1 前面有1个数据
                    System.out.println("-1");
                    return;
                }
                list.remove(list.size() - 1);//去掉最后一个数字
                
            } else {//直接添加
                list.add(new Integer(nums[i]));
            }
            
        }
        for(int i = 0; i < list.size(); i ++ ) {
            res += list.get(i);
        }
        
        System.out.println(res);
    }
}

23 任务总执行时长

java 

咱们就是说, 我只会写这种

// 本题为考试单行多行输入输出规范示例,无需提交,不计分。
import java.util.*;
public class Main {
    public static void main(String[] args) {
        
        Scanner in = new Scanner(System.in);
        String[] input = in.nextLine().split(",");
        
        int taskA = Integer.valueOf(input[0]);        
        int taskB = Integer.valueOf(input[1]);
        int nums = Integer.valueOf(input[2]);
        
        HashSet<Integer> set = new HashSet<>();
        
        if(nums != 0){
            int countA = nums;
            while(countA >= 0){
                int countB = nums - countA;
                set.add(countA * taskA + countB * taskB);
                countA -- ;
            }
        }
        
        List<Integer> ans = new ArrayList<>(set);
        
        Collections.sort(ans);
        
        System.out.println(ans);
    }
    
}

24 找数字

java

这个可以看下原链接 满分解法 好像写的更好, 没来得及看

import java.util.*;

//找数字
public class Main {

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

        int row = sc.nextInt();
        int col = sc.nextInt();

        int[][] nums = new int[row][col];
        for(int i = 0; i < row; i ++ ) {
            for(int j = 0; j < col; j ++ ) {
                nums[i][j] = sc.nextInt();
            }
        }

        HashMap<Integer, List<int[]>> map = new HashMap<>();//存<数字, {{坐标}, {坐标} ..}>
        for(int i = 0; i < row; i ++ ) {
            for(int j = 0; j < col; j ++ ) {
                List<int[]> list;

                if(map.containsKey(nums[i][j])) {
                    list = map.get(nums[i][j]);
                } else {
                    list = new ArrayList<>();
                }
                list.add(new int[]{i, j});
                map.put(nums[i][j], list);
            }
        }


        ArrayList<List<Integer>> resList = new ArrayList<>();
        for(int i = 0; i < row; i ++ ) {
            ArrayList<Integer> row_list = new ArrayList<>();//一行的结果
            for(int j = 0; j < col; j ++ ) {//该行每个数字

                int key = nums[i][j];

                List<int[]> sites = map.get(key);//每个数字的坐标集合
                if(sites.size() == 1) {
                    row_list.add(-1);
                    continue;//遍历下一个数字
                }

                int res = Integer.MAX_VALUE;
                //当坐标集合>1时 遍历每个集合
                for(int k = 0; k < sites.size(); k ++ ) {
                    int[] ints = sites.get(k);
                    int x = ints[0];
                    int y = ints[1];
                    //距离
                    int distance = Math.abs(x - i) + Math.abs(y - j);
                    if(distance == 0) continue;//否则把自己比较进去了 0 也会影响结果
                    res = Math.min(distance, res);//每个结果都更新
                }
                row_list.add(res);
            }
            resList.add(row_list);
        }


        System.out.println(resList);
    }

}

26 箱子之形摆放

java

map存<位置, 结果字符串> 

import java.util.*;

//26 箱子的摆放
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] strings = sc.nextLine().split(" ");
        String str = strings[0];
        int n = Integer.parseInt(strings[1]);

        char[] chars = str.toCharArray();

        //用map存每一行
        //k-v是 <Integer. String>
        // key是行数, values每一行的内容 把该位置的字符拼到values
        HashMap<Integer, String> res = new HashMap<>();//<0,A> <1,B> <2,C>
        for(int i = 0 ; i < str.length(); i += n ) {
            if(i / n % 2 == 0) {//偶数列 正序
                for(int j = 0; j < n; j ++ ) {
                    if(i + j < str.length()) {
                        if(res.containsKey(j)) {
                            String value = res.get(j);//必须要判断 否则会把null加进去
                            value += str.charAt(j + i);
                            res.put(j, value);
                        } else {
                            res.put(j, String.valueOf(str.charAt(j + i)));
                        }
                    }
                }
            } else {//奇数 倒序
                for(int j = 0; j < n; j ++ ) {
                    if(res.containsKey(j)) {
                        String value = res.get(n - 1 - j);
                        value += str.charAt(j + i);
                        res.put(n - 1 - j, value);
                    } else {
                        res.put(n - 1 - j, String.valueOf(str.charAt(j + i)));
                    }
                }
            }
        }

        for(String sb: res.values()) {
            System.out.println(sb);
        }

//        for(Map.Entry<Integer, String> map : res.entrySet()) {
//            System.out.println(map.getValue());
//        }

    }
}

27 异常的打卡记录

java

import java.util.*;

//找数字
public class Main {

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

        int n = sc.nextInt();//打卡记录数
        sc.nextLine();
        HashMap<Integer, List<int[]>> map = new HashMap<>();

        //遍历每个打卡记录
        ArrayList<String> alls = new ArrayList<>();
        for(int i = 0; i < n; i ++ ) {
            String str = sc.nextLine();
            //System.out.println(str);
            String[] strings = str.split(",");
            alls.add(str);
            int id = Integer.parseInt(strings[0]);
            int time = Integer.parseInt(strings[1]);
            int distance = Integer.parseInt(strings[2]);
            if(map.containsKey(id)) {
                List<int[]> list = map.get(id);
                list.add(new int[]{time, distance});
                map.put(id, list);
            } else {
                ArrayList<int[]> list = new ArrayList<>();
                list.add(new int[]{time, distance});
                map.put(id, list);
            }
        }

        ArrayList<Integer> res = new ArrayList<>();
        //遍历每个map 找重复打卡的人是不是有异常
        for(Map.Entry<Integer, List<int[]>> entry : map.entrySet()) {
            Integer id = entry.getKey();
            List<int[]> list = entry.getValue();//{时间, 地点} {} {} ..
//            if(list.size() == 1) {
//                //打卡记录一次, 不存在两次打卡距离的问题
//                //判断内部是否需要检查
//            }
            if(list.size() != 1) {//比较 任意两个数组
                for(int i = 0; i < list.size() - 1; i ++ ) {
                    int[] ints = list.get(i);
                    int time1 = ints[0];
                    int distance1 = ints[1];
                    for(int j = i + 1; i < list.size(); i ++ ) {
                        int[] ints2 = list.get(i);
                        int time2 = ints2[0];
                        int distance2 = ints2[1];
                        if(Math.abs(time1 - time2) < 60
                                && Math.abs(distance1 - distance2) > 5) {
                            res.add(id);
                        }
                    }
                }
            }
        }

        //遍历每个打卡记录 集合alls里面的
        boolean flag = true;
        StringBuilder ans = new StringBuilder();
        for(int i = 0; i < n; i ++ ) {
            String str = alls.get(i);
            String[] strings = str.split(",");
            int id = Integer.parseInt(strings[0]);
            String log = strings[3];
            String register = strings[4];
            if(res.contains(id)) {
                //System.out.println(str);
                ans.append(str);
                ans.append(" ");
                flag = false;
            } else if(!log.equals(register)) {
                //System.out.println(str);
                ans.append(str);
                ans.append(" ");
                flag = false;
            }
        }
        if(flag) System.out.println("null");
        else System.out.println(ans.toString().trim().replace(" ", ";"));

    }

}

28 最左侧冗余覆盖子串

import java.util.*;

//28 最左侧冗余覆盖子串
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String s1 = sc.nextLine();
        String s2 = sc.nextLine();

        int k = sc.nextInt();

        int n1 = s1.length();
        int n2 = s2.length();
        int len = n1 + k;

        for(int i = 0; i < n2 - len + 1; i ++ ) {//枚举子串开始的下标
            String tmp = "";
            for(int j = 0; j < len; j ++ ) {//子串长度
                tmp += s2.charAt(j + i);
            }
            if(tmp.contains(s1)) {
                System.out.println(i);
                return;
            }
        }
        System.out.println("-1");

    }
}

或者substring


        for(int i = 0; i < n2 - len + 1; i ++ ) {//枚举子串开始的下标
            String tmp = s2.substring(i, i + len);
            if(tmp.contains(s1)) {
                System.out.println(i);
                return;
            }
        }

29 最多提取子串数目

import java.util.*;

//29 最多提取子串数目
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String stra = sc.nextLine();//父字符串
        String strb = sc.nextLine();

        //char[] charsa = stra.toCharArray();//父字符串的字符数组

        int len = stra.length();
        int[] a = new int[len];//数组 保存是否已经被取过 0/1 没取过 是 0

        int i = 0, j = 0;
        int cnt = 0;
        while (i < stra.length()) {
            if (stra.charAt(i) == strb.charAt(j) && a[i] == 0) {//匹配上了
                a[i] = 1;
                //匹配上了 需要判断: 如果匹配完子串, 父串从0开始, 否则父串i++往后移动
                j ++ ;//子串往后移动
            }
            if (j == strb.length()) {//子串遍历到尾巴了 说明都匹配上了
                cnt ++ ;
                j = 0;
                i = 0;
            } else {
                i ++ ;//父串继续往后遍历
            }

        }
        System.out.println(cnt);
    }
}

30 找出通过车辆最多颜色

java: 

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] strings = sc.nextLine().split(" ");
        int n = sc.nextInt();//n秒时间

        int res = 0;
        for(int i = 0; i < strings.length - n + 1; i ++ ) {
            //类似滑动窗口, 遍历每个窗口
            int[] ints = new int[3];//3中颜色
            for(int j = i; j < n; j ++ ) {
                int num = Integer.parseInt(strings[j]);
                ints[num] ++ ;
            }//遍历完得到这个窗口的每个颜色个数

            int max = Arrays.stream(ints).max().getAsInt();
            //Arrays.stream(intArr); 转成int流, 可以求sum max min average()
            res = Math.max(res, max);
        }

        System.out.println(res);

    }
}

31 优秀学员统计

java

import java.util.*;

//26 箱子的摆放
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();//员工数量
        //sc.nextLine();

        int[] nums = new int[30];//30天 每天打卡人数
        for (int i = 0; i < 30; i++) {
            nums[i] = sc.nextInt();//第i的打卡人数
        }

        //int[] cnts = new int[n];//下标是id, 大小是打卡次数
        //换成用map存 <Integer, int[]> <id, {最早打卡时间, 打卡天数}>
        //用map存, <integer, int[2]> 员工工号 - (第一次打卡时间, 打卡数)
        HashMap<Integer, int[]> res = new HashMap<>();
   

        for (int i = 0; i < 30; i++) {//循环30天
            for(int j = 0; j < nums[i]; j ++ ) {
                int id = sc.nextInt();
                if(res.containsKey(id)) {//包含这个员工
                    int[] tmp = res.get(id);
                    tmp[1] ++;
                    res.put(id, tmp);
                } else {
                    int[] tmp = new int[2];
                    tmp[0] = i;
                    tmp[1] = 1;
                    res.put(id, tmp);
                }
            }
        }

        List<Map.Entry<Integer, int[]>> resList = new ArrayList<>(res.entrySet());
        resList.sort(new Comparator<Map.Entry<Integer, int[]>>() {
            @Override
            public int compare(Map.Entry<Integer, int[]> o1, Map.Entry<Integer, int[]> o2) {
                if(o1.getValue()[1] == o2.getValue()[1]) {
                    return o1.getValue()[0] - o2.getValue()[0];//按照打卡时间 从小到大
                } else {
                    return o2.getValue()[1] - o1.getValue()[1];//按照打卡天数 从大到小
                }
            }
        });

        StringBuilder ans = new StringBuilder();
        for(int i = 0; i < (Math.min(resList.size(), 5)); i ++ ) {//前五 员工 的 id
            ans.append(resList.get(i).getKey()).append(" ");
        }
        System.out.println(ans.substring(0, ans.length() - 1));

    }
}

考的时候写的 救命 紧张了 写的比原来复杂, 不过也是满分 

import java.util.*;

public class Main {

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

        /*
            11
            4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
            0 1 7 10
            0 1 6 10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            10
            6 10
            7 10
        */
        //员工情况 int[]

        int n = sc.nextInt();//新员工数量

        int[] empls = new int[30];//每天打卡的员工数量
        for(int i = 0; i < 30; i ++ ) {
            empls[i] = sc.nextInt();
        }

        int[] cnts = new int[n];//保存员工打卡的数量
        int[] first = new int[n];
        for(int i = 0; i < 30; i ++ ) {//天数
            for(int j = 0; j < empls[i]; j ++ ){
                int id = sc.nextInt();//员工编号
                if(cnts[id] == 0) first[id] = i;
                cnts[id] ++ ;
            }
        }

        //map <员工id, 员工打卡情况int[]{最早打卡时间, 打卡总数}>

        HashMap<Integer, int[]> map = new HashMap<>();

        for(int i = 0; i < n; i ++ ) {
            int days = cnts[i];//每个员工打卡次数
            int date = first[i];//最早打卡日期
            //i是员工id
                int[] ints = new int[2];
                ints[0] = date;
                ints[1] = days;
                map.put(i, ints);

        }

        ArrayList<Map.Entry<Integer, int[]>> list = new ArrayList<>(map.entrySet());
        list.sort(new Comparator<Map.Entry<Integer, int[]>>() {
            @Override
            public int compare(Map.Entry<Integer, int[]> o1, Map.Entry<Integer, int[]> o2) {
                if(o1.getValue()[1] == o2.getValue()[1]) {//打卡次数相同时候
                    if(o1.getValue()[0] == o2.getValue()[0]) {//打卡时间相同
                        return o1.getKey() - o2.getKey();//打卡id较小的员工
                    }
                    return o1.getValue()[0] - o2.getValue()[0];//较早打卡的员工排在前
                }
                return o2.getValue()[1] - o1.getValue()[1];//打卡次数
            }
        });

        String res = "";
        int len = Math.min(5, list.size());

        for(int i = 0; i < len; i ++ ) {
            res += list.get(i).getKey();
            if(i != len - 1) res += " ";
        }

        System.out.println(res);

    }

}

32 租车骑绿道

java 我写的

import java.util.*;

//32 租车骑绿道
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int m = sc.nextInt();//限重m
        int n = sc.nextInt();//人数n

        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();//每个人的体重
        }

        Arrays.sort(a);//从小到大排序
        int cnt = 0;
        int[] flag = new int[n]; //0
        //双指针遍历 一个从小到大, 一个从大到小
        int i = 0, j = n - 1;
        while (i < j) {
            //如果和超过限制了
            if (a[i] + a[j] > m) {
                cnt ++ ;//给最后一个++一辆车
                flag[j] = 1;
                j--;
            }

            if (a[i] + a[j] <= m) {
                cnt++;//给i和 j 分配 一辆车
                flag[i] = 1;
                flag[j] = 1;
                i++;
                j--;
            }
        }
        if(flag[i] == 0) cnt ++;//以防最中间剩下一个 没加上//比如 1 1 2 2 3 4 4 4 5 5, 剩下2

        System.out.println(cnt);
    }

}

33 相同数字的积木游戏

我写的: 

import java.util.*;
import java.util.stream.Stream;
//33 相同数字的积木游戏
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int[] a = new int[n];
        for(int i = 0; i < n; i ++ ) {
            int num = sc.nextInt();
            a[i] = num;//存进数组
        }
        //双指针 一个从前往后遍历 一个从后往前遍历
        //结果保存到res
        int res = -1;
        for(int i = 0; i < n; i ++ ) {
            int tmp = a[i];
            for(int j = n - 1; j > i; j -- ) {
                if(tmp == a[j]) {
                    res = Math.max(res, j - i);
                    break;
                }
            }
        }
        System.out.println(res);

    }
}

考试时候写的 , 救命 一紧张又写复杂了

import java.util.*;

public class Main {

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

        HashMap<Integer, List<Integer>> map = new HashMap<>();//存<数字, 位置int>

        for(int i = 0 ; i < n; i ++ ) {
            int tmp = sc.nextInt();
            if(map.containsKey(tmp)) {
                List<Integer> list = map.get(tmp);
                list.add(i);
                map.put(tmp, list);
            } else {
                ArrayList<Integer> list = new ArrayList<>();
                list.add(i);
                map.put(tmp, list);
            }
        }

        boolean flag = true;
        int ans = -1;
        for(Map.Entry<Integer, List<Integer>> entry : map.entrySet()) {
            List<Integer> list = entry.getValue();
            if(list.size() > 1) {
                flag = false;
                int res = 0;
                int len = list.size();
                for(int i = 0; i < len - 1; i ++ ) {
                    for(int j = i + 1; j < len; j ++ ) {
                        //遍历 得到一个数字的最大距离
                        res = Math.max(res, list.get(j) - list.get(i));
                    }
                }
                //每个数字的最大距离都更新
                ans = Math.max(res, ans);
            }
        }

        System.out.println(ans);

    }

}

java满分答案:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        int[] arr = new int[num];
        for(int i=0;i<num;i++){
            arr[i] = in.nextInt();
        }
        int max=-1;
        for(int i=0;i<num;i++){
            for(int j=i+1;j<num;j++){
                if(arr[i]==arr[j]){
                    max = Math.max(max,j-i);
                }
            }
        }
        
        System.out.println(max);
    }
}

34工作安排

01背包问题

f[i][j]表示只考虑前i个物品, 总体不超过j的情况下, 总价值最大是多少

状态转移 f[i][j]

        1.不选第i个物品: f[i][j] = f[i - 1][j]

        2.选第i个物品: f[i][j] = f[i - 1][j - v[i]] + w[i]

        装不下的时候 f[i][j] = f[i - 1][j] (这个情况是一定存在的

        能装下的时候, 可以选或者不选, f[i][j] = max(第一种情况, 第二种情况)   (这个情况不一定存在 要判断)

f[0][0] = 0 默认0 初始化不需要写了

c++ 代码

#include <iostream>
#include <algorithm>

using namespace std;
//01背包 二维数组做法
const int N = 1010;

int n, m; // 物品数量, 背包容量
int v[N], w[N]; // 体积 价值
int f[N][N]; // f[i][j], 前 i 个物品中体积不超过 j 的最大价值

int main()
{
    cin >> m >> n;// 输入物品数量n, 背包容量m
    for (int i = 1; i <= n; i++) cin >> v[i] >> w[i] ;//输入背包内所有东西的体积和价值

    for (int i = 1; i <= n; i++) // 物品数量<n
        for (int j = 0; j <= m; j++) // 背包
        {
            // 当前背包容量装不下第 i 个物品, 则价值等于前 i-1 个物品
            f[i][j] = f[i - 1][j];
            // 当前背包容量能装下第 i 个物品, 选择是否装第 i 个物品, 取较大的那个结果
            if (j >= v[i]) f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
        }

    cout << f[n][m] << endl;

    return 0;
}

c++ 一维数组做法:

#include <iostream>
#include <algorithm>

using namespace std;
//01背包 一维数组做法
const int N = 1010;

int n, m; // 物品数量, 背包容量
int v[N], w[N]; // 体积 价值
int f[N]; // 最大价值

int main()
{
    cin >> m >> n;// 输入物品数量, 背包容量
    for (int i = 1; i <= n; i++) cin >> v[i] >> w[i];//输入背包内所有东西的体积和价值

    for (int i = 1; i <= n; i++) // 物品数量<n
        for (int j = m; j >= v[i]; j--) // 背包
            f[j] = max(f[j], f[j - v[i]] + w[i]);//max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);

    cout << f[m] << endl;

    return 0;
}

35 预定酒店

java

import java.util.*;
import java.util.stream.Stream;

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

        String[] strs = sc.nextLine().split(" ");

        int n = Integer.parseInt(strs[0]);
        int k = Integer.parseInt(strs[1]);
        int x = Integer.parseInt(strs[2]);
        Integer[] integers =
                Arrays.stream(sc.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);


        ArrayList<int[]> list = new ArrayList<>();
        for(int i = 0; i < n; i ++ ) {
            Integer price = integers[i];
            int[] ints = new int[2];
            ints[0] = price;
            ints[1] = Math.abs(x - price);//距离价格的绝对值
            list.add(ints);
        }

        //排序 按照绝对值 和 价格大小
        list.sort(((o1, o2) -> {
            if (o1[1] == o2[1]) {//比较二者
                return o1[0] - o2[0];//如果绝对值相同 比比较数字大小 取较小的
            } else {
                return o1[1] - o2[1];//如果绝对值不同, 先按绝对值比较, 取绝对值小的
            }
        }));

        //把前k个结果保存到结果数组
        ArrayList<Integer> res = new ArrayList<>();

        //输出前k个
        for(int i = 0; i < k; i ++ ) {
            int i1 = list.get(i)[0];
            res.add(i1);
        }

        //按照值排序
        Collections.sort(res);

        for(int i = 0; i < k; i ++ ) {
            System.out.print(res.get(i));
            if(i != k - 1) System.out.print(" ");
        }

        // 参考答案中去除最后一个空格的方法:
//        StringBuilder sb = new StringBuilder();
//        for (int i = 0; i < res.size(); i++) {
//            sb.append(res.get(i)).append(" ");
//        }
//
//        System.out.println(sb.deleteCharAt(sb.length()-1));

    }
}

36 学校的位置

给学生家排序, 如果个数是奇数, 就在中间位置的学生家

如果是偶数, 就在中间两个位置的学生家之间, 题意要求输出较小的位置, 就是中间两个位置中靠左的那一个

这个用c++写更简单, java的话位移要加括号, 否则会报错

import java.util.*;

//学校的位置
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();

        int[] sites = new int[n];
        for(int i = 0; i < n; i ++ ) {
            sites[i] = sc.nextInt();//存储家庭的位置
        }
        //排序
        Arrays.sort(sites);

        int res;
        if(n % 2 == 0) {
            res = sites[(n >> 1) - 1];
        } else {
            res = sites[(n - 1) >> 1];
        }

        System.out.println(res);
    }
}

37 寻找密码

import java.util.*;

//37 寻找密码
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String[] strings = sc.nextLine().split(" ");

        HashSet<String> set = new HashSet<>();
        set.addAll(Arrays.asList(strings));

        String str = "";//结果字符串
        for (String string : strings) {

            if (check(set, string)) {
                if (string.length() > str.length()) {
                    str = string;
                }
                if (string.length() == str.length() && string.compareTo(str) > 0) {
                    str = string;
                }
            }

        }

        System.out.println(str);

    }

    public static boolean check(Set<String> set, String str) {
        String tmp = str;
        boolean flag = true;
        //最大的密码就是 str str缩短 查询set的子集就好了
        for(int i = str.length() - 1; i > 0; i -- ) {
            tmp = str.substring(0, i);
            if(!set.contains(tmp)) flag = false;
        }

        return flag;
    }

}

38 寻找关键钥匙

import java.util.*;

//38 寻找关键钥匙
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String key = sc.nextLine();
        String[] boxes = sc.nextLine().split(" ");

        for(int i = 0; i < boxes.length; i ++ ) {
            String str = "";//保存待比较的字符串
            for(int j = 0; j < boxes[i].length(); j ++ ) {
                char c = boxes[i].charAt(j);
                c = Character.toLowerCase(c);
                if(c >= 'a' && c <= 'z') str += c;
            }

            //str = str.toLowerCase();//或者这么写 字符串转换
            char[] chars = str.toCharArray();//每个box转成 char数组

            Arrays.sort(chars);

            if(String.valueOf(chars).equals(key)) {
                System.out.println(i + 1);
                return;
            }

        }

        System.out.println("-1");

    }
}

39 查找充电设备组合 TODO

java

import java.util.*;

//39 查找充电设备组合
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        ArrayList<Integer> list = new ArrayList<>();//存储充电设备的集合
        for(int i = 0; i < n; i ++ ) {
            list.add(sc.nextInt());
        }
        int p_max = sc.nextInt();//最大功率

        int max = 0;//结果数组里的最大功率
        HashSet<Integer> res = new HashSet<>();
        res.add(0);//存一个0
        for(Integer num : list){
            HashSet<Integer> tmps = new HashSet<>();//每一次遍历的临时数组
            for(Integer power : res) {//循环一遍每个结果
                int new_p = power + num;
                if(new_p <= p_max) {
                    tmps.add(new_p);//做临时数组来存, 否则会改变遍历的情况
                    max = Math.max(new_p, max);
                }
            }
            res.addAll(tmps);
        }

        System.out.println(max);

    }
}

40 知识图谱新词挖掘

import java.util.*;

//39 查找充电设备组合
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String content = sc.nextLine();
        String word = sc.nextLine();
        int len_c = content.length();
        int len_w = word.length();

        char[] words = word.toCharArray();
        Arrays.sort(words);//排序后

        int count = 0;
        for(int i = 0; i < len_c - len_w + 1; i ++ ) {
            String new_word = content.substring(i, len_w + i);
            char[] new_words = new_word.toCharArray();
            Arrays.sort(new_words);
            if(String.valueOf(new_words).equals(String.valueOf(words))) {
                count ++;
            }
        }

        System.out.println(count);
    }
}

41 静态代码扫描服务

java

记得换行的时候要 sc.NextLine(); !!!!!

import java.util.*;

//39 查找充电设备组合
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int m = sc.nextInt();//缓存一个报告的金币数m
        sc.nextLine();//换行了!!!!!

        String[] nums = sc.nextLine().split(" ");//标识序列
        String[] sizes = sc.nextLine().split(" ");//每个文件的大小

        HashMap<Integer, Integer> numsMap = new HashMap<>();//存储 标识 - 个数
        HashMap<Integer, Integer> sizeMap = new HashMap<>();//存储 标识 - 大小

        //把两个map存好
        for(int i = 0; i < nums.length; i ++ ) {
            int num = Integer.parseInt(nums[i]);
            int size = Integer.parseInt(sizes[i]);
            if(numsMap.containsKey(num)) {
                numsMap.put(num, numsMap.get(num) + 1);
            } else {
                numsMap.put(num, 1);
                sizeMap.put(num, size);
            }
        }

        int res = 0;
        for(Map.Entry<Integer, Integer> map : numsMap.entrySet()) {
            Integer key = map.getKey();//标识
            Integer value = map.getValue();//文件个数
            Integer size = sizeMap.get(key);//文件大小(扫描一次的成本价格)
            int save = 0;
            int noSave = 0;//每个标识文件 的 存和不存的需要金币数

            save = m + size;//缓存一个报告的金币数m + 扫描的成本(文件大小)
            noSave = value * size;//不缓存, 每次都扫描, 大小 * 个数

            res += Math.min(save, noSave);
        }
        System.out.println(res);

    }
}

42 不爱施肥的小布

java: 

这个向上取整没整明白 ceil为啥没取到呢, 换了朴素写法

import java.util.*;

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

        int m = sc.nextInt();//m个果林
        int n = sc.nextInt();//n天

        int[] fields = new int[m];
        for(int i = 0; i < m; i ++ ) {
            fields[i] = sc.nextInt();
        }
        Arrays.sort(fields);

        int k = 0;
        int cnt = 0;
        int res = 0;
        for(int i = 0; i < m; i ++ ) {
            k = fields[i];
            cnt += i + 1;//前i个都可以1天完成
            for(int j = i + 1; j < m; j ++ ) {
                int days = fields[j] / k;
                if(fields[j] % k != 0) {
                    days ++ ;
                }
//                int days = (int) Math.ceil(fields[j] / k);//向上取整
                cnt += days;
            }
            if(cnt <= n) {
                System.out.println(k);
                return;
            }
            cnt = 0;
        }

        System.out.println("-1");

    }
}

44 新员工座位安排系统

我写的

import java.util.*;

//44 新员工座位安排
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] strings = sc.nextLine().split(" ");

        int n = strings.length;
        int[] a = new int[n];
        boolean flag = false;
        ArrayList<Integer> indexes = new ArrayList<>();
        for(int i = 0; i < n; i ++ ) {
            a[i] = Integer.parseInt(strings[i]);
            if(a[i] == 0) {
                flag = true;//只要有0 就改为true
                indexes.add(i);//存入0点的下标
            }
        }
        if(!flag) {
            System.out.println(0);
            return;
        }

        int res = 0;
        int tmp = 0;//当前的友好值
        
        //0点所在的下标
        for (Integer index : indexes) {//枚举每个0点

            if (index != 0) {
                int l = index - 1;
                while (a[l] == 1) {
                    tmp++;
                    if (l == 0) break;
                    l--;
                }
            }
            if (index != n - 1) {
                int r = index + 1;
                while (a[r] == 1) {
                    tmp++;
                    if (r == n - 1) break;
                    r++;
                }
            }

            res = Math.max(res, tmp);
            tmp = 0;
        }
        System.out.println(res);


    }
}

45 光伏场地建设规划

java

import java.util.Scanner;
//45 光伏场地建设规划
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] strings = sc.nextLine().split(" ");

        int row = Integer.parseInt(strings[0]);
        int col = Integer.parseInt(strings[1]);

        int n = Integer.parseInt(strings[2]);
        int min = Integer.parseInt(strings[3]);//最低发电量

        int[][] a = new int[row][col];
        for(int i = 0; i < row; i ++  ) {
            for(int j = 0; j < col; j ++ ) {
                a[i][j] = sc.nextInt();
            }
        }

        if(col < n || row < n) {
            System.out.println("0");
            return;
        }


        int[][] area = new int[n][n];
        int sum = 0;
        int res = 0;
        for(int k = 0; k < row - n + 1; k ++ ) {
            for(int p = 0; p < col - n + 1; p ++ ) {//遍历所有起始点的位置
                for (int i = 0; i < n; i++) {//正方形内的值
                    for (int j = 0; j < n; j++) {
                        area[i][j] = a[i + k][j + p];//相对地址 +k +p
                        sum += area[i][j];
                    }
                }
                if(sum >= min) res ++;
                sum = 0;
            }
        }

        System.out.println(res);
    }
}

java

import java.util.Scanner;
//45 光伏场地建设规划
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] strings = sc.nextLine().split(" ");

        int row = Integer.parseInt(strings[0]);
        int col = Integer.parseInt(strings[1]);

        int n = Integer.parseInt(strings[2]);
        int min = Integer.parseInt(strings[3]);//最低发电量

        int[][] a = new int[row][col];
        for(int i = 0; i < row; i ++  ) {
            for(int j = 0; j < col; j ++ ) {
                a[i][j] = sc.nextInt();
            }
        }

        if(col < n || row < n) {
            System.out.println("0");
            return;
        }

        int count = (col - n + 1) * (row - n + 1);//总数是这些

        int[][] area = new int[n][n];
        int sum = 0;
        for(int k = 0; k < row - n + 1; k ++ ) {
            for(int p = 0; p < col - n + 1; p ++ ) {
                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < n; j++) {
                        area[i][j] = a[i + k][j + p];
                        sum += area[i][j];
                    }
                }
                if(sum < min) count --;//不满足的减掉
                sum = 0;
            }
        }

        System.out.println(count);
    }
}

46 微服务的集成测试 dfs

java

import java.util.*;

//微服务的集成测试
public class Main {

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

        int n = sc.nextInt();

        int[][] useTime = new int[n][n];
        for(int i = 0; i < n; i ++ ) {
            for(int j = 0; j < n; j ++ ) {
                useTime[i][j] = sc.nextInt();
            }
        }
        int k = sc.nextInt();//待计算 的 服务 k

        int cnt = 0;
        cnt = dfs(useTime, k - 1);
        System.out.println(cnt);

    }

    public static int dfs(int[][] useTime, int k) {
        int max = 0;
        // 计算启动服务k的时间
        //遍历k的一行数据, 得到它依赖的服务器, 获得启动时间
        for(int j = 0; j < useTime.length; j ++ ) {
            int tmp = useTime[k][j];
            if(tmp != 0 && j != k ) {
                max = Math.max(max, dfs(useTime, j));
            }
        }
        return max + useTime[k][k];//依赖的加载时间 max + 自身的加载时间
    }
}

47 字符串重新排序

java

import java.util.*;

//微服务的集成测试
public class Main {

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

        String[] strings = sc.nextLine().split(" ");

        HashMap<String, Integer> map = new HashMap<>();
        for(int i = 0; i < strings.length; i ++ ) {

            String key = arrange(strings[i]);//单词字典序
            map.put(key, map.getOrDefault(key, 0) + 1);//map存储 单词和出现次数

        }

        ArrayList<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());

        list.sort(new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                if(o2.getValue() == o1.getValue()) {//出现次数相同的情况下, 按照单词(key)的长度排序
                    if(o1.getKey().length() == o2.getKey().length()) {
                        return o1.getKey().compareTo(o2.getKey());//单词长度相同, 按照字典序升序
                    }
                    return o1.getKey().length() - o2.getKey().length();//按照单词长度升序排
                }
                return o2.getValue() - o1.getValue();//按照出现次数降序排
            }
        });

        for(int i = 0; i < list.size(); i ++ ) {

            for(int j = 0; j < list.get(i).getValue(); j ++ ) {
                System.out.print(list.get(i).getKey());
                if (i != list.size() - 1) System.out.print(" ");
            }
        }

    }
    public static String arrange(String str) {//单词内部的字典序
        //list可以排字典序
        ArrayList<Character> list = new ArrayList<>();
        for(int i = 0; i < str.length(); i ++ ) {
            list.add(str.charAt(i));
        }
        list.sort(new Comparator<Character>() {
            @Override
            public int compare(Character o1, Character o2) {
                return o1.compareTo(o2);
            }
        });
        StringBuilder res = new StringBuilder();
        for(char c : list) {
            res.append(c);
        }
        return res.toString();
    }
}

48 MVP争夺战 TODO 要背

这个有点难, dfs

java

import java.util.*;

//48 MVP争夺战
public class Main {

    static int max = -1;
    static int min = 51;
    static int[] cnt = new int[51];

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

        int t = sc.nextInt();//有得分的分钟数 [1,50]

        int[] scores = new int[t];

        int sum = 0;
        for(int i = 0; i < t; i ++ ) {
            scores[i] = sc.nextInt();
            sum += scores[i];
            cnt[scores[i]] ++ ;//得分i 出现几次cnt[i]
        }

        Arrays.sort(scores);
        max = scores[t - 1];//最末尾就是最大值
        min = scores[0];//最开头就是最大值

        //mvp得分即是 = 总分 / 人数 = 平均分
        //最小平均分 数组的最大值
        //最大平均分 总分, 即所有都是一个人投中的
        // [数组里的最大值, sum / 1]

        //按照题意 找最小平均分, 从最小平均分开始遍历, 满足条件则结束
        for(int i = max; i <= sum; i ++ ) {
            if(sum % i == 0) {//mvp平均分 能被 总分 整除 = mvp人数, 才有意义
                dfs(sum / i, 0, i, max);//dfs(总人数, 当前的分数和0, 目标平均分. 枚举位置?)
            }
        }

        System.out.println(sum);

    }

    public static void dfs(int res, int sum, int target, int p) {
        //人数是0了 说明所有人都被遍历过了, 输出结果
        if(res == 0) {//表示一种情况结束了
            System.out.println(target);
            System.exit(0);
        }
        //当 一个获得的分数sum == 目标平均分target, 遍历其余人
        if(sum == target) {
            dfs(res - 1, 0, target, max);//下一个 
            // dfs(人-1, 该人的分0, 目标分target, 继续从最大开始枚举)
            return;
        }

        //i从 最大得分 遍历到 最小得分, 枚举每个数字 选择是否用
        for(int i = p; i >= min; -- i) {
            //如果这个分数是在原数组中存在的 cnt>0 且加上之后 <= 目标分, 就把该数字用掉
            if(cnt[i] > 0 && (i + sum) <= target) {
                cnt[i] --;//用到该数字 i 
                dfs(res, sum + i, target, i);//dfs(还是当前人, 当前人的分数, 目标分, 继续从i枚举);
                cnt[i] ++ ;//放回该数字
                if(sum == 0 || (sum + i) == target) {
                    break;
                }
            }
        }
    }
}

49 贪心的商人

java

import java.util.*;

//49 贪心的商人
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int number = sc.nextInt();//商品种类
        int days = sc.nextInt();//天数

        int[] v = new int[number];
        for(int i = 0; i < number; i ++ ) {
            v[i] = sc.nextInt();//商品i的最大持有量 v[i]
        }

        int[][] w = new int[number][days];//第i个商品 的 第j天的价格
        for(int i = 0; i < number; i ++ ) {
            for(int j = 0; j < days; j ++ ) {
                w[i][j] = sc.nextInt();//
            }
        }
        
        int tmp = 0;
        int res = 0;
        for(int i = 0; i < number; i ++ ) {
            for(int j = 0; j < days - 1; j ++ ) {
                for(int k = j; k < days; k ++ ) {
                    int sell = w[i][k];
                    int buy = w[i][j];
                    tmp = Math.max((sell - buy) * v[i], tmp);//每个商品的最大利润
                }
            }
            res += tmp;
            tmp = 0;//换商品的时候置0
        }

        System.out.println(res);

    }
}

50 核酸检测人员安排

java

这也用不到dp 数学退一下就行了

import java.util.*;

//50 核酸检测人员安排
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int c_num = sc.nextInt();//采样员
        int z_num = sc.nextInt();//志愿者

        int[] k = new int[c_num];
        int sum = 0;
        for(int i = 0; i < c_num; i ++ ) {
            k[i] = sc.nextInt();//每个员工的效率
            sum += k[i];
        }
        Arrays.sort(k);//从小到大 按照效率排序

        int res = 0;
        //每个都要保证 1个
        if(z_num <= c_num) {//志愿者不足 1倍的采样员
            //从尾到头遍历 基准效率 60-600 m= 6-60
            // 所以分配给个人更好 不需要判断 M > k[i]的情况
            for(int i = c_num - 1; i > c_num - z_num - 1; i -- ) {
                res += k[i];
            }
        } //每个保证1个
        else if(z_num < c_num * 3) {//志愿者1-3倍 采样员
            int left = z_num - c_num;
            res = sum;
            for(int i = c_num - 1; i > 0; i -- ) {
                int m = (int) (k[i] * 0.1);
                if(left >= 3) {
                    res += 3 * m;
                    left -= 3;
                } else {
                    res += left * m;
                    left = 0;
                }
            }

        } else { //志愿者>= 3倍采样员的时候
            res = (int) (sum * 1.3);
        }

        System.out.println(res);
    }
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值