题解 | #数组分组#
数组分组
https://www.nowcoder.com/practice/9af744a3517440508dbeb297020aca86
import java.util.Scanner;
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
** 思路: 将输入的数字分成两组并且相等,每组为sum/2; 这样考虑的话会在等于0的时候有特殊判断:
(1)当前递归成立的结果是否为空,如果为空,剩下的数字中是否是15的倍数
(2)当前递归成立的结果结果满足要求,剩下的数组是否满足要求。
(3)这里可以通过求乘积的方法。也可以选择计数统计的方法。
(4)这道题上来没有想到3倍数一组 5 倍数这样的分组方法。所以,就在上面的思路进行了优化。
(5) 利用一个小的字典dict_cnt_flag:dict_cnt_flag[0]表示3倍数的个数,dict_cnt_flag[1]表示5倍数的个数,dict_cnt_flag[2]表示当前求的数组是否存在3的倍数,dict_cnt_flag[3]表示当前求的数组是否是5的倍数。
(6)每次递归的时候对dict_cnt_flag[2] 和 dict_cnt_flag[3]进行判断,如果当前结果集存在3或5的倍数,并且新进来的数字是3或者5的倍数时候,新进来的数字就不再添加。如果新进来3或5的倍数时,把对应标志为修改为3 和 5.
(7)每次回溯的时候弹出stack(stack用来判断满足条件的最终结果是否为空),如果加入的数字是3或5的倍数回溯的时候修改为0.
***/
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) throws IOException {
// Scanner in = new Scanner(System.in);
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
String input;
while ((input = read.readLine()) != null){
int len = Integer.parseInt(input);
int[] nums = new int[len];
String[] strnums = read.readLine().split(" ");
int[] visited = new
int[len]; //如果是5的倍数放入了标记5, 如果是3的倍数放入标记3,其他1
int total = 0;
int[] dict_cnt_flag = new int[4];
for (int i = 0; i < len; i++) {
nums[i] = Integer.parseInt(strnums[i]);
total += nums[i];
if(nums[i] != 0){
if(nums[i] % 3 == 0){
dict_cnt_flag[0]++;
}
if(nums[i] % 5 == 0){
dict_cnt_flag[1]++;
}
}
}
if (Math.abs(total) % 2 != 0) {
System.out.println("false");
} else {
int target = total / 2;
Stack<Integer> stack = new Stack<>();
boolean ans = dfs(nums, 0, 0, target, visited, stack, dict_cnt_flag);
System.out.println(ans==true ? "true" : "false");
}
}
}
public static boolean dfs(int[] nums, int index, int tmp, int target,
int[] visited, Stack<Integer> stack,int[] dict_cnt) {
if (index >= nums.length && target == tmp) {
if(stack.isEmpty()){
return (dict_cnt[0] > 0 && dict_cnt[1] > 0) ? false : true;
} else {
int cnt_3 = dict_cnt[0];
int cnt_5 = dict_cnt[1];
return (cnt_3 > 0 && cnt_5 > 0) ? false : true;
}
} else if (index >= nums.length && target != tmp) {
return false;
}
boolean p1 = false, p2 = false, p3 = false, p4 = false;
if ((nums[index] % 5 == 0 && dict_cnt[2] == 3)) {
visited[index] = 1;
p1 = dfs(nums, index + 1, tmp, target, visited, stack,dict_cnt);
} else if (nums[index] % 3 == 0 && dict_cnt[3] == 5) {
visited[index] = 1;
p2 = dfs(nums, index + 1, tmp, target, visited, stack,dict_cnt);
} else {
visited[index] = 1;
p3 = dfs(nums, index + 1, tmp, target, visited, stack,dict_cnt);
stack.push(nums[index]);
if(nums[index] % 3 == 0 ){
dict_cnt[0]--;
dict_cnt[2] = 3;
} else if(nums[index] % 5 == 0){
dict_cnt[1]--;
dict_cnt[3] = 5;
}
p4 = dfs(nums, index + 1, tmp + nums[index], target, visited, stack, dict_cnt);
int pop = stack.pop();
if(pop % 3 == 0 ){
dict_cnt[0]++;
dict_cnt[2] = 0;
} else if(pop % 5 == 0){
dict_cnt[1]++;
dict_cnt[3] = 0;
}
}
visited[index] = 0;
return p1 || p2 || p3 || p4;
}
}
