蓝桥杯 ALGO-998 娜神平衡(简单粗暴)
Posted mosqu1to
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯 ALGO-998 娜神平衡(简单粗暴)相关的知识,希望对你有一定的参考价值。
试题 算法训练 娜神平衡
资源限制
时间限制: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组。
数据规模和约定
很小,真的很小。(题目没明写,我查数据集只有: 1 <= n <= 10)
简单粗暴的思路:
- 排列后,按顺序将数优先放入A中,放进,记录
- A中放不进,放B中,放进,记录
- B中放不进,数据放回队尾,下次再枚举
- 按照记录的顺序回溯,将最后一次放入数组中的元素删除,放回队尾,下次再枚举
- 循环直到队列没有元素枚举
要点:
- 排序数据,便于枚举判断
- 使用队列存储数据,枚举失败的数据可以放回队尾,下次再枚举
- 使用栈存储枚举成功的顺序,便于回溯(正因为把顺序保存了下来,免于用递归)
- 题目要求第一个数只能放在A中,因此,只要发现B中存在第一个数,就把B当成A就行了(由答案的唯一性,可以知道一个组中的数永远待在一起,因此只要把存有第一个数的组当成A就可以了,没必要纠结于优先枚举进哪个数组)
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int q[N], first;
vector<int> a, b, pre;
int n, m, sa, sb;
int main()
scanf("%d%d", &n, &m);
for (int i = 0 ;i < n; i ++) scanf("%d", &q[i]);
first = q[0]; //保存第一个数,根据题意是一定要存进A里的
sort(q, q + n); //排序,从小到大地枚举,关键
int hh = 0, tt = n - 1; //模拟队列
while (hh <= tt) //队列为空,枚举完成
int t = q[hh ++];
sa += t;
a.push_back(t); //枚举的顺序是优先把小的数放进A
pre.push_back(1); //存储已经成功枚举的顺序, 1表示存进了A,2表示存进了B
if (abs(sa - sb) > m)
sa -= t;
a.pop_back(); //超过限制,选不了
pre.pop_back();
sb += t;
b.push_back(t); //存进B
pre.push_back(2);
if (abs(sa - sb) > m)
sb -= t;
b.pop_back(); //超过限制,选不了
pre.pop_back();
q[++ tt] = t; //目前,两组都无法放这个数,将这个数存回队列,下次再枚举
if (pre.back() == 1) q[++ tt] = a.back(), a.pop_back(), pre.pop_back(); //之前某个数放错了,撤销式地回溯,放入队列,下次再枚举
else q[++ tt] = b.back(), b.pop_back(), pre.pop_back();
sort(a.begin(), a.end()); //排序答案,题目要求
sort(b.begin(), b.end());
for (int i = 0 ; i < b.size(); i ++) //若题目要求的第一个数在B中,则替换AB数组,保证第一个数在A中
if (b[i] == first)
swap(a, b);
break;
for (int i = 0 ; i < a.size(); i ++) printf("%d ", a[i]);
puts("");
for (int i = 0 ; i < b.size(); i ++) printf("%d ", b[i]);
return 0;
吐槽:
这题应该不算难(毕竟我都会),看到其他人有用状态压缩和dfs的,我发现我的思路挺简单粗暴的,就想分享一下。
嗷,80分没过最后一个数据的,不是因为题目有问题,而是题意要求第一个数据必须在A中。
以上是关于蓝桥杯 ALGO-998 娜神平衡(简单粗暴)的主要内容,如果未能解决你的问题,请参考以下文章