AtCoder Beginner Contest 320题解 A-E

A - Leyland Number

原题链接

题目描述
给你两个整数 A A A B B B 2 ≤ A , B ≤ 9 2 \le A,B \le 9 2A,B9),输出 A A A B B B次方与 B B B A A A次方之和。

思路:幂运算

public static void solve() throws IOException {
    int a = readInt(), b = readInt();
    printWriter.println((int)Math.pow(a, b) + (int)Math.pow(b, a));
}

B - Longest Palindrome

原题链接

题目描述
给你一个字符串 S S S,求出其中的最长回文字符串的长度。

思路:模拟

  • 由于数据范围比较小,用双层for直接遍历出那个回文字符串的长度即可,最短为1。
public static void solve() throws IOException {
    String s = readString();
    int res = 0;
    for (int i = 0; i < s.length(); i++) {
        for (int j = i + 1; j < s.length() + 1; j++) {
            if (new StringBuilder(s.substring(i, j)).reverse().toString().equals(s.substring(i, j))) {
                res = Math.max(res, j - i);
            }
        }
    }
    printWriter.println(res);
}

C - Slot Strategy 2 (Easy)

原题链接

题目描述
有三个卷轴,每个卷轴上的符号分别是由数字组成的长度为 m m m的字符串 S i S_i Si,每个卷轴上都有一个按钮,同一时刻你只可以按下一个按钮,对于某一时刻 t t t,当这个按钮被按下后,卷轴上会显示 S i S_i Si上的第 ( t   m o d   m ) (t \ mod \ m) (t mod m)个字符(下标从 0 0 0开始),你需要求出最小的时间 t t t,使得三个卷轴上的字符相等,如果它们不可能相等,输出 − 1 -1 1

输入样例

4
1234
1234
1234

输出样例

8

样例解释: 0 0 0时刻按下第 1 1 1个卷轴, 4 4 4时刻按下第 2 2 2个卷轴, 8 8 8时刻按下第 3 3 3个卷轴,总共耗时 8 8 8

思路:读题+模拟+枚举

  • 由于数据范围比较小,直接枚举出三个卷轴出现相等字符的时间 t t t。但由于无法确定先按下哪个卷轴才能使 t t t最小,所以对于每个卷轴,遍历 m ∗ 3 m*3 m3的范围即可,如果还是无法让每个卷轴上的字符相等,输出 − 1 -1 1
public static void solve() throws IOException {
    int m = readInt();
    String s1, s2, s3;
    s1 = readString(); s2 = readString(); s3 = readString();
    int res = Integer.MAX_VALUE;
    for (int i = 0; i < m * 3; i++) {
        for (int j = 0; j < m * 3; j++) {
            for (int k = 0; k < m * 3; k++) {
                if (i != j && i != k && j != k) {
                    if (s1.charAt(i % m) == s2.charAt(j % m) && s1.charAt(i % m) == s3.charAt(k % m)) {
                        res = Math.min(res, Math.max(i, Math.max(j, k)));
                    }
                }
            }
        }
    }
    printWriter.println(res == Integer.MAX_VALUE ? -1 : res);
}

D - Relative Position

原题链接

题目描述
总共有 N N N个人在一个二维平面上,编号为 1 ∼ N 1 \sim N 1N,现在给你 M M M对他们之间的坐标关系,形式为 { A i A_i Ai, B i B_i Bi, X i X_i Xi, Y i Y_i Yi },即对于 A i A_i Ai来说, B i B_i Bi的坐标为 { A i A_i Ai x x x 坐标 + X i X_i Xi A i A_i Ai y y y 坐标 + Y i Y_i Yi }。请你求出这 N N N个人的坐标,如果某个人的坐标无法确定或者不唯一,则输出undecidable

思路:dfs+图论

  • 根据输入的坐标关系,很容易联想到建图,那我们就建图!而且是双向图。
  • 他们的坐标关系可以用一个字符串来表示。
  • 用一个数组 s t st st存下信息不唯一的点。
static class Edge {
    int to, pe;
    String w;
    
    public Edge(int to, int pe, String w) {
        this.to = to;
        this.pe = pe;
        this.w = w;
    }
}

static int n, m, idx = 1;
static int[] head;
static Edge[] edges;
static long inf = Long.MAX_VALUE;
static Pair[] pairs;
static boolean[] st;

public static void solve() throws IOException {
   int n = readInt(), m = readInt();
   pairs = new Pair[n + 1];
   st = new boolean[n + 1];
   head = new int[n + 1];
   Arrays.setAll(pairs, p -> new Pair());
   edges = new Edge[m * 2 + 10];
   for (int i = 1; i <= n; i++) {
       pairs[i] = new Pair(inf, inf);// 先全部初始化为无穷大,这样用于确定还没有确定信息
   }
   pairs[1].first = 0; pairs[1].second = 0;// 初始化坐标原点
   for (int i = 1; i <= m; i++) {
       int a = readInt(), b = readInt(), c = readInt(), d = readInt();
       // a->b的值为整数,b->a的值为负数
       add(a, b, c + "," + d); add(b, a, -c + "," + -d);
   }

   dfs(1);

   for (int i = 1; i <= n; i++) {
   		// 这个点没有确定信息或者信息不唯一
       if (pairs[i].first == inf && pairs[i].second == inf || st[i]) {
           printWriter.println("undecidable");
       } else {
           printWriter.println(pairs[i].first + " " + pairs[i].second);
       }
   }
}

public static void dfs(int u) {
    for (int i = head[u]; i != 0; i = edges[i].pe) {
        int to = edges[i].to;
        String w = edges[i].w;
        String[] strings = w.split(",");
        int t1 = Integer.valueOf(strings[0]), t2 = Integer.valueOf(strings[1]);// 距离
        long p = pairs[u].first, q = pairs[u].second;
        if (pairs[to].first == inf && pairs[to].second == inf) {// 第一次确定坐标
            pairs[to].first = p + t1;
            pairs[to].second = q + t2;
            dfs(to);
        } else {
            long m1 = p + t1, m2 = q + t2;
            //第一下确定的坐标信息与第二次确定的坐标信息不一致,则坐标信息不唯一
            if (pairs[to].first != m1 || pairs[to].second != m2) {
                st[to] = true;
            }
        }
    }
}

public static void add(int a, int b, String c) {
    edges[idx] = new Edge(b, head[a], c);
    head[a] = idx++;
}

E - Somen Nagashi

原题链接

题目描述
有编号为 1 ∼ N 1 \sim N 1N N N N个人从左到右站成一排进行一场执行 M M M次的活动,对于每个活动,都有一个时间 T i T_i Ti和一捆质量为 W i W_i Wi的面条,站在那排的第一个人将获得者捆面条,然后这个人要在 T i + S i T_i+S_i Ti+Si之后才能再次回到自己原来的位置,求在 M M M次活动之后每个人获得的面条质量。

输入样例

3 5
1 1 3
2 10 100
4 100 10000
10 1000 1000000000
100 1000000000 1

输出样例

101
10
1000

思路:优先队列

  • 用两个优先队列分别维护已在队伍中的人和将要回到队伍中的人的时间,感觉这题不如前两题。
public static void solve() throws IOException{
    int n = readInt(), m = readInt();
    // 维护已在队伍中的人
    PriorityQueue<Integer> people = new PriorityQueue<>();
    // 维护将要回到队伍中的人的时间
    PriorityQueue<Pair> back = new PriorityQueue<>(new Comparator<Pair>() {
        @Override
        public int compare(Pair o1, Pair o2) {
            return o1.first < o2.first ? -1 : 1;
        }
    });
    for (int i = 1; i <= n; i++) people.offer(i);
    long[] total = new long[n + 1];
    for (int i = 1; i <= m; i++) {
        int t = readInt(), w = readInt(), s = readInt();
        // 队头的人能够重新回到队伍
        while (back.size() > 0 && back.peek().first <= t) {
            people.offer(back.poll().second);
        }
        // 队伍中有人,拿上面条后进入 back队列
        if (people.size() > 0) {
            int p = people.poll();
            total[p] += w;
            back.offer(new Pair(t + s, p));
        }
    }
    for (int i = 1; i <= n; i++) {
        printWriter.println(total[i]);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值