简单题总结4 | 豆包MarsCode AI刷题

101 阅读4分钟

题目描述

小U计划进行一场从地点A到地点B的徒步旅行,旅行总共需要 M 天。为了在旅途中确保安全,小U每天都需要消耗一份食物。在路程中,小U会经过一些补给站,这些补给站分布在不同的天数上,且每个补给站的食物价格各不相同。

小U需要在这些补给站中购买食物,以确保每天都有足够的食物。现在她想知道,如何规划在不同补给站的购买策略,以使她能够花费最少的钱顺利完成这次旅行。

  • M:总路程所需的天数。
  • N:路上补给站的数量。
  • p:每个补给站的描述,包含两个数字 A 和 B,表示第 A 天有一个补给站,并且该站每份食物的价格为 B 元。

保证第0天一定有一个补给站,并且补给站是按顺序出现的。

解题思路

这个问题是一个典型的贪心问题,是一个简单版本,在中等题中还有一个类似的题目,不过多了携带食品数量的限制。在这个简单题中没有,也就是说可以购买的食品的数量没有限制。那么这道题就变得简单很多。主要是两个步骤:第一步是遍历找到比当前价格低的补给站,买够刚好到达这天的食物的数量,然后前往那天;第二步是如果没有找到比当前价格还低的补给站,也就是说当前补给站的价格最低,那么买够当天和剩余天数的食物直接到达最后一天旅行结束。

解题代码


public class Main {
    public static int solution(int m, int n, int[][] p) {
        // Edit your code here
        int result = 0;
        int food = 0;
        int i = 0;
        int min = p[i][1];
        int md = 0;
        int index = 0;
        // int secondMin = Integer.MAX_VALUE;
        // int sd = 0;
        for(int j=i+1;j<n;j++){
            if(p[j][1] < min){
                min = p[j][1];
                md = p[j][0];
                index = j;
            }
        }
        if(min != p[i][1]){
            if(food < md - p[i][0]){
                int j = i + 1;
                while(j < index){
                    if(p[j][1] < p[i][1]){
                        if(food < p[j][0] - p[i][0]){
                            result += p[i][1]*(p[j][0] - p[i][0]);
                            food = 0;
                        }
                        i = j;
                    }
                    j++;
                }
                result +=p[i][1]*(md - p[i][0])+(m - md)*min;
                food = 0;
            }else{
                food -= md - p[i][0];
            }
        }else{
            result += min*m;
            
        }
        // while(i < n - 1){
            
        // }
        // if(food < m - p[n-1][0]){
        //     result += p[n-1][1]*(m - p[n-1][0]);
        // }
        return result;
    }

    public static void main(String[] args) {
        // Add your test cases here
        System.out.println(solution(5, 4, new int[][]{{0, 2}, {1, 3}, {2, 1}, {3, 2}}));
        //System.out.println(solution(5, 4, new int[][]{{0, 2}, {1, 3}, {2, 1}, {3, 2}}) == 7);
    }
}

总结

这个题目的贪心思想就是一直找价格最小的补给站,直到最后一天。如果找不到比它价格还低的补给站,那么就可以直接买足食物然后旅行结束。

题目描述

小C正在研究一种环状的 DNA 结构,它由四种碱基ACGT构成。这种环状结构的特点是可以从任何位置开始读取序列,因此一个长度为 n 的碱基序列可以有 n 种不同的表示方式。小C的任务是从这些表示中找到字典序最小的序列,即该序列的“最小表示”。

例如:碱基序列 ATCA 从不同位置读取可能的表示有 ATCATCAACAATAATC,其中 AATC 是字典序最小的表示。

解题思路

这个问题比较简单,可以直接遍历比较得到,要注意的点就是如何将这个字符串也就是DNA序列构成环。在数据结构中,最常见的对于有索引的数组或字符串的构成环的方式就是模n操作。在这个题目中的体现就是,要得到从某个字符开始的字符串,就是从当前索引i迭代到索引(i+n-1)%n。因此只需要遍历每个字符串,与下一个字符构成的字符串相比较,找出最小的那个。

解题代码

public class Main {
    public static String solution(String dna_sequence) {
        // Please write your code here
        int n = dna_sequence.length();
        String tmp = dna_sequence;
        String new_sequence = dna_sequence;
        for (int i = 1; i < n; i++) {
            if (i > 0) {
                tmp = dna_sequence.substring(i) + dna_sequence.substring(0, (i+n-1)%n+1);
            }
            if(new_sequence.compareTo(tmp) > 0){
                new_sequence = tmp;
            }
        }

        return new_sequence;
    }

    public static void main(String[] args) {
        // You can add more test cases here
        System.out.println(solution("ATCA").equals("AATC"));
        System.out.println(solution("CGAGTC").equals("AGTCCG"));
        System.out.println(solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG").equals("AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG"));
    }
}

总结

这个问题主要就是在于如何构造环状字符串从而比较找出最小的问题,比较简单。