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

一、题目

数组分割:

小蓝有一个长度为 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

[提示]
对于第一组数据,答案为 4。(注意:大括号内的数字表示元素在数组中的下标。)
R1 = {0}, R2 = {1};此时 S1 = A0 = 6 为偶数, S2 = A1 = 6 为偶数。
R1 = {1}, R2 = {0};此时 S1 = A1 = 6 为偶数, S2 = A0 = 6 为偶数。
R1 = {0, 1}, R2 = {};此时 S1 = A0 + A1 = 12 为偶数, S2 = 0 为偶数。
R1 = {}, R2 = {0, 1};此时 S1 = 0 为偶数, S2 = A0 + A1 = 12 为偶数。
对于第二组数据,无论怎么选择,都不满足条件,所以答案为 0。

对于 20% 的评测用例,1 ≤ N ≤ 10。
对于 40% 的评测用例,1 ≤ N ≤ 10^2。
对于 100% 的评测用例,1 ≤ T ≤ 10, 1 ≤ N ≤ 10^3 , 0 ≤ Ai ≤ 10^9。

二、分析

2023年第十四届蓝桥杯JavaB组省赛真题及解析_蓝桥杯javab组真题解析-CSDN博客 思路是借鉴上面的文章

题目解读:

我们要先把数组A = [A0, A1,…, AN−1]分成两个子集R1和R2,且这两个子集的中元素的和都为偶数,现在是要我们找出有多少个符合条件的R1,(我们不用看R2,因为两个是互补的)

解题思路:

 解题过程中并没有将A分成两个子数组,而是找A中有多少个偶数和计数,偶数记为O,奇数记为J,然后看偶数和奇数组合方式刚好能在R1中得到偶数,求这个组合方式,

对于偶数,不管怎么选,最后加起来都是偶数,(有选这个偶数和不选这个偶数两种情况,所以是2的O次方)

对于奇数,我们要选则偶数个,用到高中的C(m,n)

        C(0,0)= 1=2^0,0个奇数中选择0个,有1种组合方法;

        C(0,2)+C(2,2)= 2=2^1,2个奇数中选,有1种组合方法;

        C(0,4)+C(2,4)+C(4,4)=8=2^3,4个奇数中选,有8种组合方法;

可以得到一个公式2^(J-1) 种组合方法。

代码:

package lan2023;

import java.util.Scanner;
public class C数组分割 {

	public static int mod = 1000000007;
	public static void main(String[] args) {
		//键盘录入n种数据
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] a;
		
		//当我们的数据不为零的时候依次求每组数据
		while(n > 0) {
			//录入数组的长度
			int m = sc.nextInt();
			a = new int[m];
			//再录入数组的元素
			for(int i = 0; i < m; i++) {
				a[i] = sc.nextInt();
			}
			
			//看偶数和奇数各有多少个
			int O = 0, J = 0;
			for(int i = 0; i < m; i++) {
				if(a[i] % 2 == 0) {
					O++;
				} else {
					J++;
				}
			}
			
			int count = 1;
			if(J % 2 != 0) System.out.println(0);//奇数是奇数个的话,我们直接输出0,表示无论怎么选,和都不会是偶数
			else {
				if(J == 0) J = 1;
				for(int i = 0; i < O+J-1; i++) {
					count =count * 2 % mod; 
				}
				System.out.println(count);
				
			}
			n--;//表示已经判断完一组数据,总数里减1
			
		}
		
	}
}

在写的时候有一点没写出来,就是输出最终的结果的时候 写在了n--,的后面,不能写在这,因为我们算每一组有多少个不同的R1时,要输出结果,每组会有不同的输出结果。

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值