Atcoder Begginer Contest349 A~E Solution题解

A - Zero Sum Game

题目:
玩家1~N玩若干个一对一游戏,赢得加1分,输的减一分,初始分数为0,现在给出1 ~ N-1号玩家的最后分数,输出N号玩家的分数。

思路:
所有玩家的总分数加起来应该是0,最后一名的玩家分数为 0 - 前N-1名玩家的总分数

static void solve() throws IOException {
    int n = pInt(in.readLine());
    int[] a = pIntArray(1);
    int sum = 0;
    for (int i = 1;i < n; i ++) sum += a[i];
    out.println(-sum);
}

B - Commencement

题目:
判断一个字符串S是否符合:第i(i>1)次时S中是否有0个或者两个字符的出现次数等于i;

思路:
用哈希表统计一下,然后暴力枚举 1 ≤ i ≤ 100 1 \le i \le 100 1i100 的情况即可

static void solve() throws IOException {
   String s = in.readLine();
   int[] st = new int[26];
   for (int i = 0; i < s.length(); i ++) {
       st[s.charAt(i) - 'a'] ++;
   }
   for (int i = 1; i <= 100; i ++) {
       int cnt = 0;
       for (int j = 0; j < 26; j ++) {
           if (st[j] == i) {
               cnt ++;
           }
       }
       if (cnt != 0 && cnt != 2) {
           out.println("No");
           return;
       }
   }
   out.println("Yes");
}

C - Airport Code

题目:
给一个长度为3且全部为大写字母的字符串T,判断是否能从全是小写字母的字符串S中按照下面的方法转换而来:

  • 从S中拿出长度为3的子序列并转化为大写字母
  • 从S中拿出长度为2的子序列并转化为大写字母,最后加上 X

思路:
模拟统计一下即可

static void solve() throws IOException {
    String s = in.readLine();
    String t = in.readLine();
    int n = s.length(), m = t.length(), idx = 0;
    for (int i = 0; i  < n; i ++) {
        if (s.charAt(i) - 32 == t.charAt(idx)) {
            idx += 1;
            if (idx == m) {
                out.println("Yes");
                return;
            }
        }
    }
    // 长度为2的子序列,在最后加上 `X`
    if (idx == 2 && t.charAt(m - 1) == 'X') {
        out.println("Yes");
    } else {
        out.println("No");
    }
}

D - Divide Interval

题目:
给一个 L 到 R-1 递增为1的序列S(L,R), 将其切分为若干个子序列,每一个子序列满足 S ( 2 i j , 2 i ( j + 1 ) ) S(2^ij, 2^i(j+1)) S(2ij,2i(j+1))(i,j为非负数),要求切分后的子序列数量最少。

思路:
要求切分的子序列实际上是子序列的长度为较大2的次幂,那每次找到较大的2次幂即可

static void solve() throws IOException {
    String[] ins = pStringArray();
    long l = pLong(ins[0]), r = pLong(ins[1]);
    List<long[]> ans = new LinkedList<>();
    while (l < r) {
    	// 找到较大的长度 满足2次幂
        int idx = 0;
        while (l % (1L << (idx + 1)) == 0 && l + (1L << (idx + 1)) <= r) {
            idx += 1;
        }
        ans.add(new long[] {l, l + (1L << idx)});
        l += 1L << idx;
    }
    out.println(ans.size());
    for (long[] p : ans) {
        out.println(p[0] + " " + p[1]);
    }
}

E - Weighted Tic-Tac-Toe

题目:
两个人A和B玩井字棋,每个格子都有一个值 A i , j A_{i,j} Ai,j (保证 ∑ i = 1 3 ∑ j = 1 j A i , j \sum^3_{i=1} {\sum^{j}_{j=1}{A_{i,j}}} i=13j=1jAi,j 为奇数);A先手,游戏获胜的条件:

  • 任一方水平、竖直、对角方向连续3个格子同一个颜色的获胜;
  • 如果格子不能上色,那么总值最大的一方获胜

两人采用最优策略获胜,判断哪方最终会获胜

思路:
数据量比较小,使用爆搜;爆搜出口:连续3个格子相同颜色或者不能上色时;使用 1-1 分别表示A和B的颜色,在切换对方时只需要取相反数即可,同时还能计算双方总值的差值。
返回值为获胜方的颜色;

static final int WHITE = 0;
// Aoki
static final int BLUE = -1;
// Takahashi
static final int RED = 1;
static boolean check(int[][] st, int color) {
    int d1 = 0, d2 = 0;
    for (int i = 0; i < 3; i ++) {
        int row = 0, col = 0;
        for (int j = 0; j < 3; j ++) {
            if (st[i][j] == color) row ++;
            if (st[j][i] == color) col ++;
        }
        if (row == 3 || col == 3) return true;
        if (st[i][i] == color) d1 ++;
        if (st[2 - i][i] == color) d2 ++;
    }
    return d1 == 3 || d2 == 3;
}
static int dfs(int[][] st, long[][] map, int idx, in
    // 检查上一步是否获胜
    if (check(st, -color)) return -color;
    // 没办法上色,比较 dis
    if (idx == 9) {
        return dis > 0 ? RED : BLUE;
    }
    for (int i = 0; i < 3; i ++) {
        for (int j = 0; j < 3; j ++) {
            if (st[i][j] == WHITE) {
                st[i][j] = color;
                int t = dfs(st, map, idx + 1, -color
                st[i][j] = WHITE;
                if (t == color) {
                    return color;
                }
            }
        }
    }
    return -color;
}
static void solve() throws IOException {
    long[][] map = new long[3][3];
    for (int i = 0; i < 3; i ++) {
        String[] ins = pStringArray();
        for (int j = 0; j < 3; j ++) {
            map[i][j] = pLong(ins[j]);
        }
    }
    int[][] st = new int[3][3];
    if (dfs(st, map, 0, RED, 0L) == RED) {
        out.println("Takahashi");
    } else {
        out.println("Aoki");
    }
}

模板代码:

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Example {

    static void solve() throws IOException {

    }

    public static void main(String[] args) throws IOException {
        int t = 1;
//        t = Integer.parseInt(in.readLine());
        while (t -- > 0) {
            solve();
        }
        in.close();
        out.flush();
        out.close();
    }

    private static InputStream is = System.in;
    static {
        try {
            is = Files.newInputStream(Paths.get("F:\\Notes\\Algorithm\\Problems\\java\\java\\src\\main\\java\\input.txt"));
        } catch (Exception e) {
            is = System.in;
        }
    }
    private static final BufferedReader in = new BufferedReader(new InputStreamReader(is));
    private static final PrintWriter out = new PrintWriter(System.out);
    private static int pInt(String s) {
        return Integer.parseInt(s);
    }
    private static long pLong(String s) {
        return Long.parseLong(s);
    }
    private static String[] pStringArray() throws IOException {
        return in.readLine().split(" ");
    }
    private static int[] pIntArray(int start) throws IOException {
        String[] s = pStringArray();
        int[] arr = new int[start + s.length];
        for (int i = start, j = 0; i < arr.length; i++, j ++) {
            arr[i] = Integer.parseInt(s[j]);
        }
        return arr;
    }

    private static long[] pLongArray(int start) throws IOException {
        String[] s = pStringArray();
        long[] arr = new long[start + s.length];
        for (int i = start, j = 0; i < arr.length; i++, j ++) {
            arr[i] = Long.parseLong(s[j]);
        }
        return arr;
    }
}

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值