陕西赛区 蓝桥杯 Java b组 冲省一 每日一敲 第二天(苦涩。。

蓝桥杯2023年第十四届省赛真题-数组分割

时间限制: 3s 内存限制: 576MB 提交: 1353 解决: 279

题目描述

小蓝有一个长度为 N 的数组 A = [A0, A1,..., AN−1]。现在小蓝想要从 A 对应的数组下标所构成的集合 I = {0, 1, 2, . . . , N − 1} 中找出一个子集 R1,那么 R1在 I 中的补集为 R2。记 S1=∑r∈R1Ar,S2 =∑r∈R2Ar,我们要求 S1 和 S2 均为偶数,请问在这种情况下共有多少种不同的 R1。当 R1 或 R2 为空集时我们将 S1 或 S2 视为 0。

输入格式

第一行一个整数 T,表示有 T 组数据。

接下来输入 T 组数据,每组数据包含两行:第一行一个整数 N,表示数组 A 的长度;第二行输入 N 个整数从左至右依次为 A0, A1, . . . , AN−1,相邻元素之间用空格分隔。

输出格式

对于每组数据,输出一行,包含一个整数表示答案,答案可能会很大,你需要将答案对1000000007 进行取模后输出。

样例输入
2
2
6 6
2
1 6
样例输出
4
0

思路

陕西赛区 蓝桥杯 Java b组 冲省一 每日一敲 第二天(苦涩。。_第1张图片


家人们,有点鲁莽了啊。。第二天尝试真题,咱看别人的代码都看不明白。。。

自己的思路跟别人代码沾不上边哈~(⊙﹏⊙)苦涩

下面欣赏一下正确代码


package demo;

import java.util.Scanner;

public class Demo {

    /*
     2
     2
     6 6
     2
     1 6

     * */
    static long mod = 1000000007;
    static int cifang;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt();
        while (T > 0) {
            T--;
            int n = scanner.nextInt();
            int even = 0;
            int odd = 0;
            cifang = 0;
            for (int i = 1; i <= n; i++) {
                int num = scanner.nextInt();
                if (num % 2 == 0)
                    even++;
                else {
                    odd++;
                }
            }
//  System.out.println(even+" even");
//  System.out.println(odd+" odd");
            if (odd == 0 && even > 0) {
                cifang = even;
            }
//   System.out.println(Math.pow(2, even)%mod);
            else if (odd % 2 == 0)
                cifang = odd - 1 + even;
            else {
                cifang = -1;
            }
//  System.out.println(cifang+" p");
            long ans = 1;
            if (cifang == -1)
                System.out.println(0);
            else {
                while (cifang > 0) {
                    ans = (ans * 2) % mod;
                    cifang--;
                }
                System.out.println(ans);
//                    System.out.println(" "+odd+" "+even);
            }
        }


    }
}

咱现场学习一下


    static long mod = 1000000007;
    static int cifang;
为什么定义在main方法之前

这两个变量 `static long mod = 1000000007;` 和 `static int cifang;` 被定义在 `main` 方法之前,主要是为了在整个类中都能够访问它们,并且它们的值在不同的方法中可以共享和修改。

1. `static long mod = 1000000007;`: 这个变量用于存储一个常数,即1000000007。通常在计算过程中,为了避免处理过大的数字,我们会取模。在这个问题中,`mod` 的存在是为了在计算过程中对结果取模,以防止溢出。由于这个值在整个类中都是常量,定义为 `static` 可以使其在其他静态方法中直接访问。

2. `static int cifang;`: 这个变量用于存储一个计数值,具体在代码中表示可能的子集 `R1` 的数量。同样,由于它在多个方法中都需要使用和修改,定义为 `static` 使得不同方法可以共享这个变量。

总的来说,将这两个变量定义为 `static`,使得它们在整个类中都是共享的,可以在不同的方法中进行读取和修改。这在某些情况下很有用,特别是当这些变量不同方法中都需要使用到时。


```java
static long mod = 1000000007;
static int cifang;
```

这里定义了两个静态变量,`mod` 用于存储取模的值,`cifang` 用于记录一种情况下R1的计数。

```java
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int T = scanner.nextInt();
    while (T > 0) {
        T--;
        int n = scanner.nextInt();
        int even = 0;
        int odd = 0;
        cifang = 0;
```

在 `main` 方法中,程序首先读取输入中的测试数据组数 `T`。然后,通过一个 `while` 循环处理每组测试数据。在每组数据中,首先读取数组的长度 `n`,并初始化一些计数变量。

1. **奇数和偶数的个数统计:**
   ```java
   for (int i = 1; i <= n; i++) {
       int num = scanner.nextInt();
       if (num % 2 == 0)
           even++;
       else {
           odd++;
       }
   }
   ```
   这个循环遍历数组中的每个元素,根据元素值的奇偶性分别增加 `even` 或 `odd` 的计数。`even` 记录偶数的个数,`odd` 记录奇数的个数。

2. **根据奇偶数的个数确定 cifang 的值:**
   ```java
   if (odd == 0 && even > 0) {
       cifang = even;
   }
   else if (odd % 2 == 0)
       cifang = odd - 1 + even;
   else {
       cifang = -1;
   }
   ```
   - 如果奇数个数为零且偶数个数大于零,说明数组中没有奇数,所有子集都满足条件(即和都是偶数)。所以,`cifang` 取偶数个数。
   - 如果奇数个数为偶数,说明可以从奇数中选出偶数个,再加上所有的偶数,这样得到的子集满足条件。所以,`cifang` 取奇数个数。
   - 如果奇数个数为奇数,无法通过选择来使得和为偶数,因此设定 `cifang` 为 -1,表示无法满足条件。

3. **计算结果:**
   ```java
   long ans = 1;
   if (cifang == -1)
       System.out.println(0);
   else {
       while (cifang > 0) {
           ans = (ans * 2) % mod;
           cifang--;
       }
       System.out.println(ans);
   }
   ```
   - 如果 `cifang` 为 -1,说明无法满足条件的子集,直接输出 0。
   - 否则,通过循环计算 2^{cifang}的取模结果,即满足条件的子集数量,并输出结果。

总体来说,这段代码通过统计奇数和偶数的个数,灵活地处理了不同情况下满足条件的子集数量,并使用位运算的方式高效计算结果。


这道题还是一知半解的,太难了┭┮﹏┭┮

怎么就根据奇偶数的个数确定 cifang 的值了呢
   else if (odd % 2 == 0)
       cifang = odd - 1 + even;

这个看不懂。。

你可能感兴趣的:(蓝桥杯,算法,java)