资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
娜娜是一个特别可爱的女孩子,作为学神的她最近在情感方面出现了一点点小问题。
她暗恋的琦琦是一名学霸,他只喜欢长得漂亮和学习很好的女生。
娜娜学习确实很神,但是她在琦琦面前却总是表现不出平时的神力。
琦琦感受到了娜娜对他的爱,但是他还是觉得娜娜的学习并不是特别好,于是他出了一道题给娜娜。
“娜娜,我们之间的关系需要在不断深入的同时保持一定的平衡,不可以你总是强势或者我总是弱势。”
琦琦给了娜娜一些两两不等的数,希望娜娜能把这些数分成两组A和B,满足以下条件:
1:每一次只能操作一个数,即只取出一个数分入A中或B中;
2:每一次操作完成后,A中数之和与B中数之和的差不能超过r。
新时代的丘比特们啊,帮帮娜娜吧!
输入格式
输入共两行。
第一行包括两个正整数n和r,n表示琦琦一共给了n个数,r的意义见题目描述。
第二行包括n个正整数,分别表示琦琦给的n个数。
输出格式
输出共两行,分别把A与B两组数按从小到大输出。
注意输入中n个数的第一个必须分入A组。
琦琦保证这样的输出唯一。
样例输入
4 10
9 6 4 20
样例输出
4 6 9
20
样例说明
先把4和6先后分入A组,再把20分入B组,最后把9分入A组。
数据规模和约定
很小,真的很小。
解答,一开始自己想没想出来,参考了一下网上的解法,发现是使用的dfs算法,深度优先也就是先把初始数组元素往a数组先放如果是满足题目给的条件也就是两数组之和的差小于等于r那么就可以放A数组里面,如果不能往A中放入,此时我们把先前的状态进行回溯操作,也就是把visited数组置为0,然后把A数组当前元素清除长度–,放b数组中,当然由于原始数组第一个元素一定放在a所以b数组的元素一定是从原始数组的第二个元素开始放这个要注意:具体代码如下:
#include<iostream>
using namespace std;
int n,r,f;//f用来标记是否达成条件
int a[1000];
int b[1000];
int x[1000];
int lena,lenb;
int visited[1000]={0};
void sort(int *a,int n){
int flag;
for (int i = 0; i < n; i++)
{
flag = 0;
for (int j = n-1; j>i; j--)//这里每次把最小的数字往前冒 j的大小需要固定;
{
if(a[j]<a[j-1]){
int temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
flag =1;
}
}
if (flag==0)
{
break;
}
}
}
int sum(int *a,int len){
int sum = 0;
for (int i = 0; i < len; i++)
{
sum+=a[i];
}
return sum;
}
void dfs(int k){
if (abs(sum(a,lena) - sum(b,lenb))>r)
{
return;
}
if (k>=n)//此时可以输出结果
{
sort(a,lena);
sort(b,lenb);
for (int i = 0; i < lena; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
for (int i = 0; i < lenb; i++)
{
cout<<b[i]<<" ";
}
cout<<endl;
f=1;
return;
}else{
for (int i = 0; i < n; i++)
{
if (f==1)
{
return;
}
if (lena==0 && abs(x[i] -sum(b,lenb))>r)
{
continue;
}
if (visited[i]==0)
{
visited[i]=1;
a[lena++] = x[i];//由于这个下标是由0开始的而长度是1开始所以每次下标变化都要先与赋值变化
dfs(k+1);
visited[i]=0;
a[--lena ] = 0;
}
}
for (int i = 1; i < n; i++)
{
if (f==1)
{
return;
}
if (visited[i]==0)
{
visited[i]=1;
b[lenb++] = x[i];
dfs(k+1);
visited[i]=0;
b[--lenb ] = 0;
}
}
}
}
int main(){
//变量自动初始化为0;
cin>>n>>r;
for (int i = 0; i < n; i++)
{
cin>>x[i];
}
dfs(0);
return 0;
}