时间限制: 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
家人们,有点鲁莽了啊。。第二天尝试真题,咱看别人的代码都看不明白。。。
自己的思路跟别人代码沾不上边哈~(⊙﹏⊙)苦涩
下面欣赏一下正确代码
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;
这个看不懂。。