题解 | #C++数组分组#
数组分组
http://www.nowcoder.com/practice/9af744a3517440508dbeb297020aca86
思路
1.将因数为5的元素分出去,并求和S5
2.将因数为3的元素分出去,并求和S3
3.接收其他元素并求和S0
4.计算S5和S3的差值a
5.判断(S0-a)%2是否为0;为0则表示有可能实现分组,反之则一定不行
6.问题转化为能否把剩余元素分为两组S1,S2,使其满足S1+S2=S0 S1-S2=a
7.再将问题转化为能否在S0中找到S1或S2 S1=(S0+a)/2 S0 a 均为已知
#include <bits/stdc++.h> using namespace std; bool findsub(int findarr,vector<int> arr,int i) { if(findarr==0)//直到需要查找的数为0是,则代表查找完毕,不然则一直进行查找 return true; else if(i==0)//如果一直没有找到最终结果,找到数组开头时,如果当前查找数和数组首位相等,则返回true否则返回false return arr[i]==findarr; /*else if(arr[i]>findarr)//这一选项没有考虑到负数的情况 return findsub(findarr, arr, i-1);*/ else //走到这里代表着当前数组还没找完,并且还没到数组开头 { return findsub(findarr, arr, i-1)||//第一种情况不选当前位置的数据,判断当前位置之前的数据能否构成查找数 findsub(findarr-arr[i], arr, i-1);//第二种情况,选择当前位置,判断当前位置的以前的数据能否构成(查找数-arr[i]) } } int main() { int num; while(cin>>num) { int get; int sum3=0; int sum5=0; int s0=0; vector<int> arr; for(int i=0;i<num;i++) { cin>>get;//分5 if(get%5==0) { sum5+=get; continue; } if(get%3==0)//分3 { sum3+=get; continue; } else//接收其余元素,并求和 { s0+=get; arr.push_back(get); } } int a= abs(sum5-sum3); int flag=(s0-a)%2; if(flag!=0)//如果剩余的数不能均分,则不能实现分组 cout<<"false"<<endl; else { //s1+s2=s0 //s1-s2=a //因此如果能在剩余的数组中找到一组数构成s1 //则剩下的数能够成s2 //把s1放在s5、s3中较小的 //把s2放在s5、s3中较大的 int finds1 = (s0+a)/2; int i=arr.size(); bool ret=findsub(finds1,arr,i-1); if(ret) cout<<"true"<<endl; else cout<<"false"<<endl; } } return 0; }