题解 | #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;
}