Codeforces Round 918 (Div. 4) 解题报告 | 珂学家 | 偏序 + 扩展Dijkstra


前言


整体评价

属于VP,感觉还是能AK的,E是偏序题,F是改版的迪杰特斯拉。


A. Odd One Out

题型: 签到

t = int(input())
 
for i in range(t):
    a, b, c = list(map(int, input().split()))
    if a == b:
        print (c)
    elif a == c:
        print (b)
    else:
        print (a)

B. Not Quite Latin Square

题型: 签到

模拟一下就好

′ A B C ′ − ′ A x B ′ + ′ ? ′ 'ABC' - 'AxB' + '?' ABCAxB+?

如果有多个空的话,可能需要借助DFS搜索会比较好

其他思路:

  • 找到’?'所在的位子
  • 然后标记清除
t = int(input())

acc = sum([ord(c) for c in 'ABC'])
for _ in range(t):
    arr = [input() for _ in range(3)]
    for i in range(3):
        tmp = sum(ord(c) for c in arr[i])
        if acc != tmp:
            tc = chr(acc - tmp + ord('?'))
            print(tc)
            break

C. Can I Square?

思路: 模拟

即累加和为平方数

import math

t = int(input())
for _ in range(t):
    n = int(input())
    acc = sum(map(int, input().split()))
    r = int(math.sqrt(acc))
    if r * r == acc:
        print("YES")
    else:
        print("NO")

D. Unnatural Language Processing

思路: 划分型DP + 构造

t = int(input())

def isV(c) -> bool:
    if c == 'a' or c == 'e':
        return True
    return False

for _ in range(t):
    n = int(input())
    s = input()

    vis = [False] * (n + 1)
    source = [-1] * (n + 1)

    vis[0] = True
    for i in range(2, n + 1):
        if isV(s[i - 1]) and not isV(s[i - 2]) and vis[i - 2]:
            vis[i] = True
            source[i] = i - 2
        elif i >= 3 and not isV(s[i - 1]) and isV(s[i - 2]) and not isV(s[i - 3]) and vis[i - 3]:
            vis[i] = True
            source[i] = i - 3

    res = []
    x = n
    while source[x] != 0:
        res.extend(s[source[x]:x][::-1])
        res.append('.')
        x = source[x]
    res.extend(s[:x][::-1])

    print (''.join(res[::-1]))

E. Romantic Glasses

思路: map的应用

很有意思的一道题,感觉像map典题

引入奇数累加和,偶数累计加和,然后作差

如果map中存在,则必然存在一个区间,满足要求

在codeforce中,因为map要hack,所以要引入随机值进行异或

import random


t = int(input())
for _ in range(t):
    n = int(input())
    arr = list(map(int, input().split()))

    h = random.randint(1, 1 << 30)
    cnt = {h}
    s1, s2 = 0, 0
    ok = False
    for i in range(n):
        if i % 2 == 0:
            s2 += arr[i]
        else:
            s1 += arr[i]
        d = s1 - s2
        if (d ^ h) in cnt:
            ok = True
            break
        cnt.add(d ^ h)
    if ok:
        print ("YES")
    else:
        print ("NO")


F. Greetings

思路: 偏序类问题

t = int(input())

class Bit(object):

    def __init__(self, n):
        self.n = n
        self.arr = [0] * (n + 1)
    def query(self, p) -> int:
        r = 0
        while p > 0:
            r += self.arr[p]
            p -= p & -p
        return r
    def update(self, p, d) -> None:
        while p <= self.n:
            self.arr[p] += d
            p += p & -p

    def expr(self):
        print (self.arr)

for _ in range(t):
    n = int(input())
    ops = []

    ys = []
    for i in range(n):
        l, r = list(map(int, input().split()))
        ops.append((0, l, r))
        ops.append((1, r, 0))
        ys.append(l)
        ys.append(r)

    ops.sort(key=lambda x: (x[1], x[0]))
    ys.sort(key=lambda x: x)

    m = len(ys)
    hp = {}
    for (i, k) in enumerate(ys):
        hp[k] = i+1
    bit = Bit(m)

    res = 0
    for (c, d, er) in ops:
        if c == 0:
            res += bit.query(m) - bit.query(hp[er] - 1)
            bit.update(hp[er], 1)
        elif c == 1:
            bit.update(hp[d], -1)
    print (res)
        

F. Bicycles

思路: 改版dij

扩展节点,引入新节点(cityId, cycleId)

这样就能求解出最优的解来了

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        AReader sc = new AReader();
        int t = sc.nextInt();
        while (t-- > 0) {
            int n = sc.nextInt(), m = sc.nextInt();
            List<int[]> []g = new List[n];
            Arrays.setAll(g, x->new ArrayList<>());
            for (int i = 0; i < m; i++) {
                int u = sc.nextInt() - 1, v = sc.nextInt() - 1;
                int w = sc.nextInt();
                g[u].add(new int[] {v, w});
                g[v].add(new int[] {u, w});
            }
            int[] vs = new int[n];
            for (int i = 0; i < n; i++) {
                vs[i] = sc.nextInt();
            }

            long inf = Long.MAX_VALUE / 10;
            long[][] path = new long[n][n];
            for (int i = 0; i < n ;i++) {
                Arrays.fill(path[i], inf);
            }

            PriorityQueue<long[]> pq = new PriorityQueue<>(Comparator.comparing(x -> x[1]));
            pq.offer(new long[] {0, 0, 0});
            path[0][0] = 0;

            while (!pq.isEmpty()) {
                long[] cur = pq.poll();
                int vid = (int)cur[0];
                int sid = (int)cur[2];

                if (path[vid][sid] < cur[1]) {
                    continue;
                }

                int ss = vs[vid] < vs[sid] ? vid : sid;

                for (int[] e: g[vid]) {
                    int v = e[0], w = e[1];
                    if (path[v][ss] > cur[1] + (long)vs[ss] * w) {
                        path[v][ss] = cur[1] + (long)vs[ss] * w;
                        pq.offer(new long [] {v, path[v][ss], ss});
                    }
                }
            }

            System.out.println(Arrays.stream(path[n - 1]).min().getAsLong());
        }
    }

    static
    class AReader {
        private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        private StringTokenizer tokenizer = new StringTokenizer("");
        private String innerNextLine() {
            try {
                return reader.readLine();
            } catch (IOException ex) {
                return null;
            }
        }
        public boolean hasNext() {
            while (!tokenizer.hasMoreTokens()) {
                String nextLine = innerNextLine();
                if (nextLine == null) {
                    return false;
                }
                tokenizer = new StringTokenizer(nextLine);
            }
            return true;
        }
        public String nextLine() {
            tokenizer = new StringTokenizer("");
            return innerNextLine();
        }
        public String next() {
            hasNext();
            return tokenizer.nextToken();
        }
        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

//        public BigInteger nextBigInt() {
//            return new BigInteger(next());
//        }
        // 若需要nextDouble等方法,请自行调用Double.parseDouble包装
    }

}

写在最后

Codeforces Round 918 (Div. 4) 解题报告 | 珂学家 | 偏序 + 扩展Dijkstra_第1张图片

你可能感兴趣的:(Codeforce解题报告,java,算法,力扣,leetcode,开发语言,code)