Codeforces Round #597 (Div. 2)

Codeforces Round #597 (Div. 2)

原题地址

#题目分数是否AC
AGood ol’ Numbers Coloring1000
BRestricted RPS1200
CConstanze’s Machine1400
DShichikuji and Power Grid1900
EHyakugoku and Ladders2300
FDaniel and Spring Cleaning2300





A. 题目

题目类型   数论

题意

  


分析

  


时间复杂度

   O ( log ⁡ n ) O( \log n ) O(logn)


代码
public static void solve() throws IOException {
    int a = nextInt();
    int b = nextInt();

    if (gcd(a, b) == 1) pw.println("Finite");
    else pw.println("Infinite");
}

public static int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}






B. 题目

题目类型   贪心

题意

  


分析

   尽量赢。遍历 Bob 的出拳序列,如果 Alice 存在可以赢得拳就先出,如果没有就先空着。最后统计赢得个数是否满足题意,如果满足就把空着得位置用没出得拳补上就行。


时间复杂度

   O ( n ) O( n ) O(n)


代码
public static void solve() throws IOException {

    int n = nextInt();

    int[] a = new int[130];
    a['R'] = nextInt();
    a['P'] = nextInt();
    a['S'] = nextInt();


    char[] s = next().toCharArray();
    char[] ss = new char[n];
    System.arraycopy(s, 0, ss, 0, n);

    for (int i = 0; i < n; i++) {
        switch (s[i]) {
            case 'R': if (a['P']-- > 0) s[i] = '-'; break;
            case 'P': if (a['S']-- > 0) s[i] = '-'; break;
            case 'S': if (a['R']-- > 0) s[i] = '-'; break;
        }
    }

    int cnt = 0;
    for (char i : s) if (i == '-') cnt++;

    if (cnt >= (int) Math.ceil((double) n / 2)) {
        pw.println("YES");
        for (int i = 0; i < n; i++) {
            if (s[i] == '-') {
                switch (ss[i]) {
                    case 'R': pw.print('P'); break;
                    case 'P': pw.print('S'); break;
                    case 'S': pw.print('R'); break;
                }
            } else {
                if (a['R']-- > 0) pw.print('R');
                else if (a['P']-- > 0) pw.print('P');
                else if (a['S']-- > 0) pw.print('S');
            }
        }
        pw.println();
    } else {
        pw.println("NO");
    }

}
    





C. 题目

题目类型   思维 组合数 动态规划

题意

  


分析

   对于相连 n n n u u u 不同个数贡献的不同字符串的个数进行打表发现是斐波那契额数列。那么就可以统计出每段相连 n n n u u u 的贡献然后用乘法原理计算结果。


时间复杂度

   O ( n ) O(n) O(n)


代码
static final int Mod = 1000000007;

public static void solve() throws IOException {

    char[] s = next().toCharArray();

    int[] TB = new int[s.length + 1];

    makeTB(TB, 1000000007);

    long ans = 1;
    for (int i = 0; i < s.length; i++) {
        if (s[i] == 'w' || s[i] == 'm') {
            pw.println(0);
            return ;
        }

        if (s[i] == 'n') {
            int j = i;
            while (j + 1 < s.length && s[j + 1] == 'n') j++;
            ans = (ans * TB[j - i + 1]) % Mod;
            i = j;
        }

        if (s[i] == 'u') {
            int j = i;
            while (j + 1 < s.length && s[j + 1] == 'u') j++;
            ans = (ans * TB[j - i + 1]) % Mod;
            i = j;
        }
    }

    pw.println(ans);

}

public static void makeTB(int[] TB, int Mod) {
    TB[0] = 1; TB[1] = 1;
    for (int i = 2; i < TB.length; i++)
        TB[i] = (TB[i - 1] + TB[i - 2]) % Mod;
}


打表代码

public static void solve() throws IOException {
    StringBuilder s = new StringBuilder();
    for (int i = 0; i < 10; i++) {
        TreeSet<StringBuilder> set = new TreeSet<>();
        dfs(s, 0, set);

        set.add(s);
        pw.println("n : " + i + "  cnt :" + set.size());

        s.append('n');
    }

}

public static void dfs(StringBuilder s, int step, TreeSet<StringBuilder> set) {
    if (step + 1 >= s.length()) return ;

    StringBuilder s1 = new StringBuilder(s);
    StringBuilder s2 = new StringBuilder(s);
    if (s1.charAt(step) == 'n' && s1.charAt(step + 1) == 'n') {
        s1.replace(step, step + 2, "m");
        set.add(s1);
        dfs(s1, step + 1, set);
    }

    set.add(s2);
    dfs(s2, step + 1, set);
}
    





D. 题目

题目类型  

题意

  


分析

  


时间复杂度

   O ( n 2 log ⁡ n 2 ) O( n^2 \log n^2 ) O(n2logn2)


代码
    static Edge[] edge;
    static int idx;
    static int[] ans1;
    static int ans1Idx;
    static Edge[] ans2;
    static int ans2Idx;

    public static void solve() throws IOException {
        int n = nextInt();

        init(n);

        Vertex[] v = new Vertex[n + 1];
        for (int i = 1; i <= n; i++) v[i] = new Vertex(nextInt(), nextInt());

        int[] c = new int[n + 1];
        for (int i = 1; i <= n; i++) c[i] = nextInt();

        int[] k = new int[n + 1];
        for (int i = 1; i <= n; i++) k[i] = nextInt();

        for (int i = 1; i <= n; i++) edge[idx++] = new Edge(0, i, c[i]);

        for (int i = 1; i <= n; i++)
            for (int j = i + 1; j <= n; j++)
                edge[idx++] = new Edge(i, j, getCost(v, k, i, j));


        long ans = kruskal(n);

        pw.println(ans);

        pw.println(ans1Idx);
        for (int i = 0; i < ans1Idx; i++) pw.print(ans1[i] + " ");
        pw.println();

        pw.println(ans2Idx);
        for (int i = 0; i < ans2Idx; i++) pw.println(ans2[i].from + " " + ans2[i].to);

    }

    public static long kruskal(int n) {
        int[] fa = new int[n + 1];
        int[] rank = new int[n + 1];
        for (int i = 0; i < fa.length; i++) {
            fa[i] = i;
            rank[i] = 1;
        }

        Arrays.sort(edge, 0, idx, new Comparator<Edge>() {
            @Override
            public int compare(Edge o1, Edge o2) {
                return Long.compare(o1.cost, o2.cost);
            }
        });

        long re = 0;
        int cnt = 0;
        for (int i = 0; i < idx; i++) {
            Edge e = edge[i];
            if (!same(fa, e.from, e.to)) {
                unite(fa, rank, e.from, e.to);
                re += e.cost;
                cnt++;

                if (e.from == 0) {
                    ans1[ans1Idx++] = e.to;
                } else {
                    ans2[ans2Idx++] = e;
                }
            }

            if (cnt == n) break;
        }

        return re;
    }

    public static int find(int[] fa, int x) {
        return fa[x] == x ? x : (fa[x] = find(fa, fa[x]));
    }

    public static void unite(int[] fa, int[] rank, int x, int y) {
        x = find(fa, x);
        y = find(fa, y);

        if (x == y) return ;

        if (rank[x] < rank[y]) fa[x] = y;
        else {
            fa[y] = x;
            if (rank[x] == rank[y]) rank[x]++;
        }
    }

    public static boolean same(int[] fa, int x, int y) {
        return find(fa, x) == find(fa, y);
    }

    public static void init(int n) {
        edge = new Edge[n * n + n];
        idx = 0;
        ans1 = new int[n + 1];
        ans1Idx = 0;
        ans2 = new Edge[n + 1];
        ans2Idx = 0;
    }

    public static long getCost(Vertex[] v, int[] k, int i, int j) {
        return (long) (k[i] + k[j]) * (Math.abs(v[i].x - v[j].x) + Math.abs(v[i].y - v[j].y));
    }



    /*******************************************************************************************************************************/

    static class Edge {
        int from, to;
        long cost;

        public Edge(int from, int to, long cost) {
            this.from = from;
            this.to = to;
            this.cost = cost;
        }
    }

    static class Vertex {
        int x, y;

        public Vertex(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }






E. 题目

题目类型  

题意

  


分析

  


时间复杂度

   O ( ) O( ) O()


代码
这里粘贴代码





F. 题目

题目类型  

题意

  


分析

  


时间复杂度

   O ( ) O( ) O()


代码
这里粘贴代码





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值