Codeforces Round 893 (Div. 2) 题解 A-C

A - Buttons

原题链接

题目描述
有三个按钮A,B,C,分别能被按A,B,C次,其中按钮A只能由人a按下,按钮B只能由人b按下,按钮C可以由任意一人按下,现在ab轮流按按钮,a先按,谁不能按按钮谁就输,问谁能赢。

思路:奇偶性

  • 如果C是偶数,那么ab都可以按C按钮 C 2 \frac {C} {2} 2C次,那么就比AB谁大,谁大谁赢,相等则B赢,因为A先按。
  • 如果C是奇数,那么a可以多按一次C,那么就比A+1B谁大,谁大谁赢,相等则B赢,因为A先按。
public static void solve() throws IOException {
    int a = readInt(), b = readInt(), c = readInt();
    if (c % 2 == 0) {
        if (a + c / 2 <= b + c / 2) {
            printWriter.println("Second");
        } else {
            printWriter.println("First");
        }
    } else {
        if (a + c / 2 + 1 > b + c / 2) {
            printWriter.println("First");
        } else {
            printWriter.println("Second");
        }
    }
}

B - The Walkway

原题链接

题目描述
有编号为 1 ∼ n 1 \sim n 1nn个长凳和m个卖饼干的商人位于人行道附近,Petya 站在人行道的起点,他一定会经过这n个长凳,由于走路太累,他会在以下任意一个条件满足时吃一块饼干。

  • 在第i个长凳附近有一个卖饼干的人,那么 Petya 会从卖饼干的人那里买一块饼干并立即吃掉。
  • Petya 还没有吃饼干。然后 Petya 会从背包中拿出一块饼干并立即吃掉(例如位于起点处)。
  • 距离 Petya 吃上一块饼干至少过去了 d分钟,Petya 会从背包中拿出一块饼干并立即吃掉。

为了尽量减少 Petya 吃饼干的数量,你需要m个商人中移除一个商人
求出吃饼干的最少数量 和 满足达到这个数量的移除商人的方案数

输入样例

7 //测试数据的个数
6 2 2
2 5
8 3 2
3 5 8
10 4 9
2 8 9 10
30 5 8
6 8 15 24 29
30 5 8
6 8 12 20 27
8 8 3
1 2 3 4 5 6 7 8
2 2 2
1 2

输出样例

3 1
4 1
4 4
6 4
5 2
7 7
1 1

思路:技巧 + 模拟

  • 先求出不移除任何商人所需要吃的饼干总数
  • 再枚举移除第 i个商人后需要吃的饼干,统计到map
public static void solve() throws IOException {
    int n = readInt(), m = readInt(), d = readInt();
    int[] cookies = new int[m + 5];
    for (int i = 1; i <= m; i++) cookies[i] = readInt();
    cookies[0] = 1 - d;//方便处理左边界,可以解决cookies[1] = 1的特殊情况
    cookies[m + 1] = n + 1;//方便处理右边界
    int sum = 0;
    // 先求出不移除任何商人所需要吃的饼干总数
    for (int i = 1; i <= m + 1; i++) {
    	// 技巧:多减一个1防止出现d的倍数导致sum多加一个1
    	// 例如 d=2,cookies=[2,6],第一个商人到第二个商人间实际只需要吃 4,6两块饼干
        sum += (cookies[i] - cookies[i - 1] - 1) / d + 1;
    }
    sum--;//减去上面第 m+1处多加的一个饼干

    Map<Integer, Integer> map = new HashMap<>();
    // 枚举移除第 i个商人后需要吃的饼干
    for (int i = 1; i <= m; i++) {
        int cur = sum - 1;//减去在第 i个商人处的一个饼干
        cur -= (cookies[i] - cookies[i - 1] - 1) / d;//减去在第 i-1~i个商人间的饼干
        cur -= (cookies[i + 1] - cookies[i] - 1) / d;//减去在第 i~i+1个商人间的饼干
        cur += (cookies[i + 1] - cookies[i - 1] - 1) / d;//加上第i-1~i+1个商人处的饼干

        map.put(cur, map.getOrDefault(cur, 0) + 1);
    }
    int min = Integer.MAX_VALUE;
    for (int p : map.keySet()) min = Math.min(min, p);
    printWriter.println(min + " " + map.get(min));
}

C - Yet Another Permutation Problem

原题链接

题目描述
Alex在玩一个游戏,给定 1 ∼ n 1 \sim n 1n的整数,将这些整数排成一个序列a,对于序列中的第 i个数,计算得出 d i d_i di = gcd( a i a_i ai, a ( i   m o d   n ) + 1 a_{(i\ mod\ n) + 1} a(i mod n)+1),你所组成的排列最终得到的分数就是 d中不同数字的个数,要使得分数最高,应该组成怎样的排列?输出最终的排列(可能有多个,输出其一)

输入样例

4 //测试数据的个数
5
2
7
10

输出样例

1 2 4 3 5 
1 2 
1 2 3 6 4 5 7 
1 2 3 4 8 5 10 6 9 7

思路:模拟

  • 让存在倍数关系的数字呆在一起
public static void solve() throws IOException {
    int n = readInt();
    Set<Integer> set = new HashSet<>();
    List<Integer> list = new ArrayList<>();
    for (int i = 1; i <= n; i++) {
        if (!set.contains(i)) list.add(i);
        set.add(i);
        int j = i;
        //让存在倍数关系的数字呆在一起
        while (2 * j <= n && !set.contains(2 * j)) {
            set.add(2 * j);
            list.add(2 * j);
            j *= 2;
        }
    }
    for (int p : list) printWriter.print(p + " ");
    printWriter.println();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值