试题 算法训练 娜神平衡
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
娜娜是一个特别可爱的女孩子,作为学神的她最近在情感方面出现了一点点小问题。
她暗恋的琦琦是一名学霸,他只喜欢长得漂亮和学习很好的女生。
娜娜学习确实很神,但是她在琦琦面前却总是表现不出平时的神力。
琦琦感受到了娜娜对他的爱,但是他还是觉得娜娜的学习并不是特别好,于是他出了一道题给娜娜。
“娜娜,我们之间的关系需要在不断深入的同时保持一定的平衡,不可以你总是强势或者我总是弱势。”
琦琦给了娜娜一些两两不等的数,希望娜娜能把这些数分成两组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组。
数据规模和约定
很小,真的很小。
利用状压枚举状态 分成两个数组进行判断 因为必有解 所以排完序后从小到大挨个放就好
最后 判断一下首位在哪个数组中
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+5;
typedef long long ll;
int a[N],val1[N],val2[N];
int n,r,tem,idx1,idx2;
void init(){
memset(val1,0,sizeof(val1));
memset(val2,0,sizeof(val2));
idx1=idx2=0;
}
bool check(){
int x=0,y=0,sum1=0,sum2=0,flag=1;
sum1=val1[++x];
while(abs(sum1-sum2)<=r&&flag){
flag=0;
if(abs(sum1+val1[x+1]-sum2)<=r&&x+1<=idx1){
x++;
flag=1;
sum1+=val1[x];
}
if(abs(sum1-val2[y+1]-sum2)<=r&&y+1<=idx2){
y++;
flag=1;
sum2+=val2[y];
}
}
if(x==idx1&&y==idx2){
return true;
}
else{
return false;
}
}
void print1(){
for(int j=1;j<=idx1;j++){
printf("%d ",val1[j]);
}
printf("\n");
}
void print2(){
for(int j=1;j<=idx2;j++){
printf("%d ",val2[j]);
}
printf("\n");
}
int main(){
scanf("%d%d",&n,&r);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
tem=a[1];
sort(a+1,a+1+n);
for(int i=0;i<(1<<n);i++){
int judge=0;
init();
val1[++idx1]=a[1];
for(int j=1;j<n;j++){
if((1<<j)&i){
val1[++idx1]=a[j+1];
}
else{
val2[++idx2]=a[j+1];
}
}
if(check()){
for(int j=1;j<=idx1;j++){
if(val1[j]==tem)
judge=1;
}
if(judge){
print1();
print2();
}
else{
print2();
print1();
}
break;
}
}
return 0;
}