EOJ Monthly 2019.1 唐纳德先生与这真的是签到题吗 【数学+暴力+multiset】
传送门:https://acm.ecnu.edu.cn/contest/126/
C. 唐纳德先生与这真的是签到题吗
单测试点时限: 6.0 秒
内存限制: 1024 MB
唐纳德先生在出月赛的过程中,准备了一个签到题:给定一个长度为 n 的非负整数序列 a1,a2,…,an,对于所有的 i,j (1≤i<j≤n),求出 ai+aj,并对这 n(n−1)2 个数进行排序输出。
很不幸的是,唐纳德先生把题目的输入搞丢了,现在只剩下输出。你能把输入还原出来吗?
输入
输入共 t (1≤t≤300) 组测试数据。
每组测试数据有两行,第一行是一个整数 n (3≤n≤300)。
第二行含有 n(n−1)2 个整数 b1,b2,…,bn(n−1)/2 (b1≤b2≤⋯≤bn(n−1)/2),用空格隔开。
输入保证所有 t 组数据 n 的和不超过 300。
输出
对于每组数据,输出一行 n 个整数 a1,a2,…,an,用空格隔开,表示答案。
输入保证存在至少一组解满足 0≤ai≤109 对 1≤i≤n 成立,但是你输出的解可以不在这个范围内:只要满足 ai 都是非负整数,且与题目要求相符,就视为正确。如有多解,输出任意一解。
样例
2
3
3 5 6
4
3 4 5 5 6 7
1 2 4
1 2 3 4
解题思路:
原题:BZOJ 2797
a1+a2, a1+a3 肯定是给出的 b 序列里最小的那两个。
即 a1+a2 = b1, a1+a3 = b2;
但是三个未知数,我们还需要一条方程才能解。
那么 a2+a3 到底是第几个 b 呢?
暴力枚举 第 3 ~ N 个 b,找出正解 a2+a3;
得到 a2+a3 = bi ( 3 <= i <= N);
如何判断当前枚举的 b 是不是正解 a2+a3 呢?
通过上面三条方程我们可以 解出当前 a2+a3 = bi 情况下的 a1, a2, a3.
那么 把 b 序列中的 a1+a2, a1+a3, a2+a3删掉,最小的肯定是 a1+a4 了
已知 a1 可以求出 a4, 继续把 b 序列里的 a1+a4, a2+a4, a3+a4 删掉,最小的肯定是 a1+a5 了
已知 a1 可以求出 a5。。。。。。。。。
如果这其中任何一个过程出现了 求得的 a 为 负数,说明当前的 a2+a3 不是正解。
如果这其中任何一个过程出现了 在 b 序列里找不到要删除的数,说明当前的 a2+a3 不是正解。
那么怎么维护这个可以删除元素 并且 能自动排序的 b 序列呢
运用 C++ stl 里的 multiset ,一个默认将元素从小到大排序,支持查找 删除的二叉树数据结构。
通过枚举 a2+a3 只要找到一个 可行的 a2+a3 把答案输出即可。
(这道题只需要求一组可行的答案即可,BZOJ 2797 要求所有满足条件的答案,其实就是找到就行 和 全部暴力的区别)
AC code:
#include <set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MAXN = ;
int N, len;
LL num[MAXN*MAXN];
multiset<LL>s;
LL ans[MAXN]; bool check(LL A23)
{
s.clear();
//printf("len:%d\n", len);
for(int i = ; i <= len; i++){ ///把 题目给的 b 序列 丢进 multiset
//printf("%lld\n", num[i]);
s.insert(num[i]);
} s.erase(s.find(A23)); //删除 a2+a3 //puts("zjy");
if((num[]+num[]+A23)&1LL) return false;
LL tmp = (num[]+num[]-A23)/2LL;
//printf("tmp:%lld\n", tmp);
ans[] = tmp; //a1
ans[] = num[]-tmp; //a2
ans[] = A23-ans[]; //a3
//printf("A23:%lld tmp:%lld ans3:%lld\n", ans[3]);
if(ans[] < || ans[] < || ans[] < ) return false; ///前三个答案有其中一个为 0 即不满足条件
//if(!(ans[1] <= ans[2] && ans[2] <= ans[3] && ans[1] <= ans[3])) return false; LL value = ;
LL it = ;
for(int i = ; i <= N; i++){ ///算出 ai 的答案
value = *s.begin();
ans[i] = value-ans[];
if(ans[i] < ) return false; for(int j = ; j < i; j++){ ///删除掉 ai+a1, ai+a2,这类, 保证 b 序列里最小的是 a1 + ai+1
it = ans[i]+ans[j];
if(s.find(it) == s.end()) return false; /// b 序列里没有 ai+aj 这个数, 即 当前的这组结果无法算出答案序列里的值
s.erase(s.find(it)); ///把 ai+aj 从 b 序列里删除
}
}
return true;
} int main()
{
int T_case;
scanf("%d", &T_case);
while(T_case--){
scanf("%d", &N);
len = (N*(N-))/;
for(int i = ; i <= len; i++){
scanf("%lld", &num[i]);
} for(int i = ; i <= len; i++){
if(i == || num[i] != num[i-]){
if(check(num[i])) {
//printf("A23:%lld\n", num[i]);
break;
}
}
}
//puts("zjy");
//printf("N:%d\n", N); for(int i = ; i <= N; i++){
//printf("i:%d ans:%lld ",i, ans[i]);
printf("%lld ", ans[i]);
}
puts(""); } return ;
}
EOJ Monthly 2019.1 唐纳德先生与这真的是签到题吗 【数学+暴力+multiset】的更多相关文章
- EOJ Monthly 2019.2 (based on February Selection) D 进制转换 【数学 进制转换】
任意门:https://acm.ecnu.edu.cn/contest/140/problem/D/ D. 进制转换 单测试点时限: 2.0 秒 内存限制: 256 MB “他觉得一个人奋斗更轻松自在 ...
- EOJ Monthly 2019.2 题解(B、D、F)
EOJ Monthly 2019.2 题解(B.D.F) 官方题解:https://acm.ecnu.edu.cn/blog/entry/320/ B. 解题 单测试点时限: 2.0 秒 内存限制: ...
- 2019年牛客多校第一场B题Integration 数学
2019年牛客多校第一场B题 Integration 题意 给出一个公式,求值 思路 明显的化简公式题,公式是分母连乘形式,这个时候要想到拆分,那如何拆分母呢,自然是裂项,此时有很多项裂项,我们不妨从 ...
- EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)
传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f( ...
- EOJ Monthly 2019.2
题解 A 回收卫星 #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/s ...
- EOJ Monthly 2019.2 (based on February Selection) F.方差
题目链接: https://acm.ecnu.edu.cn/contest/140/problem/F/ 题目: 思路: 因为方差是用来评估数据的离散程度的,因此最优的m个数一定是排序后连续的,所以我 ...
- EOJ Monthly 2019.2 (based on February Selection) D.进制转换
题目链接: https://acm.ecnu.edu.cn/contest/140/problem/D/ 题目: 思路: 我们知道一个数在某一个进制k下末尾零的个数x就是这个数整除kx,这题要求刚好末 ...
- EOJ Monthly 2019.3 A
A. 钝角三角形 单点时限: 3.0 sec 内存限制: 512 MB QQ 小方以前不会判断钝角三角形,现在他会了,所以他急切的想教会你. 如果三角形的三边长分别为 a, b, c (a≤b≤c), ...
- eoj monthly 2019.11
原题 T1 纸条 题目大意: 给出一个长度为n的字符串,其中m位未知,对于每一位未知的字母,有k个备选字母,最终答案为备选字母按字典序排序后的第x个. 题解: 签到题-- 按照题目意思直接写就可以了. ...
随机推荐
- 在 Azure 上创建和链接 MySQL 数据库
本快速入门介绍了如何使用 Azure 门户创建并连接 MySQL 数据库.在本教程中完成的所有操作均符合 1 元试用条件. 开始之前如果您还没有 Azure 账户,可以申请 1 元试用账户 步骤1:创 ...
- [android] android通信协议
1.数据区分 手机端:常量存储 服务器端:数据库建表存储 2.数据来源 android,ios,pc,wap 3.数据采集,数据挖掘 IMEI:设备编号 IMSI:SIM卡编号 4.数据加密 4.1R ...
- Java 基础(4)——常量 & 注释
hello 呀,今天的内容超简单( ̄︶ ̄)↗并且,还有暗藏福利哟~~ 常量 常量 就是常常不变的量,第一次定义之后,就不会发生改变了.可能这就是 “常量” 的来源吧哈哈哈(玩笑). 一般来说,常量的定 ...
- three.js 在vscode的智能提示
安装nodejs.启动或者重启vscode,打开控制台,输入命令 npm install --save @types/three 回车, 会多了个node_modules文件夹,再试试智能感知,出来. ...
- java 从Excel 输出和输入
本文实现了使用java 从数据库中获得对象,并存入集合中, 然后输出到Excel,并设置样式 package com.webwork; import java.io.File; import java ...
- “没有用var声明的为全局变量”这种说法不准确
结论: “没有用var声明的变量为全局变量”这样的说法不太正确,需要在这句话前面加一个前提,如果①变量前面没有用var声明,②在变量所在在的作用域链中没有这个变量名称,则设置该变量为全局变量. 代码 ...
- C#打印代码运行时间
使用以下方法可以准确的记录代码运行的耗时. System.Diagnostics.Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); / ...
- 任务十六:零基础JavaScript编码(四)
任务目的 在上一任务基础上继续JavaScript的体验 深入学习JavaScript的事件机制及DOM操作 学习事件代理机制 学习简单的表单验证功能 学习外部加载JavaScript文件 任务描述 ...
- 九、background及相关所有属性
先看看如下所示的视效图应该如何显示背景阴影? #header { height: 180px; background: url(../images./bg.png) no-repeat center ...
- 面向对象之property
property功能 以调用数据属性的方式(不用加括号)调用方法 方法定义成数据属性(方法本应该是动词) # 定义property之前 class People: def __init__(self, ...