Binary String Game----Java题解

Binary String Game

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 524288K,其他语言1048576K
Special Judge, 64bit IO Format: %l

题目描述 

你有一个长度为 n 的二进制字符串 s,现在你可以进行无限次以下操作:

选取字符串中的恰好m 个位置然后反转他们的值,即异或上 1。

全 0 状态下的分数为 0,令第 i 个位置最后为 1 能带来的贡献分数为 ai​,求贡献分数最大为多少,并给出操作方案。

输入描述:

第一行两个正整数 n,m(1≤m≤n≤103)n,m(1≤m≤n≤103)。
第二行给定长度为 n 的 01 字符串 s。
接下来一行给定 n 个整数 ai(−10^9≤ai≤10^9)

输出描述:

第一行两个数 ans,p 分别表示答案和你给出操作方案的操作次数,你的操作方案需要满足p≤5×104。

接下来 p 行每行一个 01 字符串表示这次操作中每个位置是否异或上 1,需要保证 1 的个数恰好为m。

示例1

输入

复制

3 2
000
2 3 9

输出

复制

12 1
011

思路解析:

  1. 情况1: 如果n==m,即全部翻转,只有两种情况,翻转后收益更大,则翻转,如果翻转后收益变小,则不翻转。
  2. 情况2:如果m==1,这样我们总能使一个位置单独翻转,如果这个位置上收益大于0并且当前翻转情况为0.则让他翻转,如果这给位置上收益小于等于0并且当前翻转情况为1,则让他翻转。
  3. 情况3:此时,我们可以根据每个位置上的值,得到最优答案,和需要翻转的次数。
    1. 如果翻转次数为偶数,则两两配对进行翻转。例如有五个位置,现在前两个位置需要翻转,且m=3,则可以 10110 和01110,这样就完成了翻转。
    2. 如果翻转次数为奇数:(思路:先将翻转次数从奇数变为偶数,然后再两两配对进行翻转。)
      1. 但是m为偶数,说明无论怎么翻转,都不能奇数个位置翻转成功,则此时要改变一个绝对值最小的位置,改变他的最优翻转状态,使翻转次数变为偶数。
      2. 如果m为奇数,那我们任意翻转一次,就可以使翻转次数从奇数变为偶数

代码实现:

import java.util.Arrays;
import java.util.Scanner;

/**
 * @ProjectName: study3
 * @FileName: Ex20
 * @author:HWJ
 * @Data: 2023/11/10 21:11
 *
 * 牛客练习赛D -- 暂时未做出来。
 */
public class Main {
    static char[] s;
    static char[] t;
    static int n;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        n = input.nextInt();
        int m = input.nextInt();
        String str = input.next();
        s = str.toCharArray();
        int[] num = new int[n];
        t = new char[n];
        long ans = 0;
        for (int i = 0; i < n; i++) {
            num[i] = input.nextInt();
            if (s[i] == '1') {
                ans += num[i];
            }
            if (num[i] > 0) t[i] ='1';
            else t[i] = '0';
        }

        long init = ans;
        if (n == m){ //特判
            for (int i = 0; i < n; i++) {
                if (s[i] == '1') init -= num[i];
                else if (s[i] == '0') init += num[i];
            }
            if (init >= ans){
                System.out.println(init + " 1");
                for (int i = 0; i < n; i++) {
                    System.out.print(1);
                }
            }else {
                System.out.println(ans + " 0");
            }
            return;
        }
        ans = 0;
        for (int i = 0; i < n; i++) {
            if (t[i] == '1') ans+=num[i];
        }
        int nums = 0;
        if (m == 1){
            for (int i = 0; i < n; i++) {
                if (s[i] != t[i]) nums++;
            }
            System.out.println(ans + " " + nums);
            char[] f = new  char[n];
            Arrays.fill(f, '0');
            for (int i = 0; i < n; i++) {
                if (s[i] != t[i]){
                    f[i] = '1';
                    System.out.println(String.valueOf(f));
                    f[i] ='0';
                }
            }
            return;
        }
        nums = 0;
        for (int i = 0; i < n; i++) {
            if (s[i] != t[i]) nums++;
        }
        if (nums % 2 == 1){
            if (m % 2 == 0){
                int mn = Integer.MAX_VALUE;
                int id = 0;
                for (int i = 0; i < n; i++) {
                    if (Math.abs(num[i]) < mn){
                        mn = Math.abs(num[i]);
                        id = i;
                    }
                }
                ans -= mn;
                t[id] ^= 1;
                nums = 0;
                for (int i = 0; i < n; i++) {
                    if (s[i] != t[i]) nums++;
                }
                System.out.println(ans + " " + nums);
            }else {
                for (int i = 0; i < m; i++) {
                    t[i] ^= 1;
                }
                nums = 0;
                for (int i = 0; i < n; i++) {
                    if (s[i] != t[i]) nums++;
                }
                System.out.println(ans + " " + (nums + 1));
                for (int i = 0; i < n; i++) {
                    if (i < m) System.out.print(1);
                    else System.out.print(0);
                }
                System.out.println();
            }
        }else {
            System.out.println(ans + " " + nums);
        }

        while (true){
            int[] data = find();
            if (data[0] == -1) break;
            char[] res = new char[n];
            Arrays.fill(res, '0');
            res[data[0]] = '1';
            s[data[0]] ^= 1;
            int j = 0;
            for (int i = 0; i < m - 1;) {
                if (j != data[0] && j!= data[1]){
                    res[j] = '1';
                    i++;
                }
                j++;
            }
            System.out.println(String.valueOf(res));
            Arrays.fill(res, '0');
            res[data[1]] = '1';
            s[data[1]] ^= 1;
            j = 0;
            for (int i = 0; i < m - 1;) {
                if (j != data[0] && j!= data[1]){
                    res[j] = '1';
                    i++;
                }
                j++;
            }
            System.out.println(String.valueOf(res));
        }
    }

    public static int[] find(){
        int[] data = new int[2];
        data[0] = -1;
        data[1] = -1;
        for (int i = 0; i < n; i++) {
            if (s[i]  != t[i]){
                if (data[0] == -1) data[0] = i;
                else {
                    data[1] = i;
                    break;
                }
            }
        }
        return data;
    }
}

你可能感兴趣的:(数据结构,算法)