当前位置: 首页 > news >正文

【 前缀和 单调双向队列 化环为链】P7590 回旋加速器(2021 CoE-II C)|普及+

本文涉及知识点

C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频
C++队列、双向队列

P7590 回旋加速器(2021 CoE-II C)

题目描述

回旋加速器( Cyclotron \text{Cyclotron} Cyclotron)是利用磁场和电场使带电粒子作回旋运动并经高频电场反复加速的装置,是高能物理中的重要仪器。

我们来研究回旋加速器的一个简化模型。将回旋加速器视为一个环形的轨道,轨道上设置了 n n n 个加速腔,依次编号为 1 1 1 n n n。将一束质子从某个加速腔导入,在导入时,质子束的动能为零。第 i i i 个加速腔能够为质子束提供 e i e_i ei 的动能 ,质子束从第 i i i 个加速腔运行到第 i + 1 i + 1 i+1 个加速腔会损失 d i d_i di 的动能(由于是环形轨道,编号为 n n n 的加速腔后面是编号为 1 1 1 的加速腔)。

给定每个加速腔能够提供的动能值以及质子束在各个加速腔之间运行所损失的动能值,试确定质子束能否绕环形轨道运行一周。如果能够成功,应该选择从哪个加速腔导入质子束。质子束在两个加速腔之间运行时,动能不能为零,但质子束刚到达加速腔时,动能可以为零,因为可以立即获得加速腔所提供的动能。

输入格式

输入包含多组测试数据。

输入第一行包含一个整数 T T T,表示测试数据的组数。接着是一个空行。

接下来是 T T T 组数据,每组数据由三行构成。两组数据之间有一个空行。

每组数据的第一行是一个整数 n n n,表示加速腔的个数。第二行一共 n n n 个整数,依次表示编号为 i i i 的加速腔能够提供的动能 e i e_i ei。第三行一共 n n n 个整数,依次表示质子束从第 i i i 个加速腔运行到第 i + 1 i + 1 i+1 个加速腔所损失的动能 d i d_i di。由于是环形轨道,第三行的第 n n n 个整数表示的是从第 n n n 个加速腔运行到第 1 1 1 个加速腔时损失的动能。

输出格式

每组数据输出一行。如果质子束无法环绕加速器运行一周,输出 Failed!,否则输出导入质子束的加速腔编号,如果有多个加速腔可供选择,选择具有最小编号的加速腔。

输入输出样例 #1

输入 #1

13
1 2 3
2 3 4

输出 #1

Failed!

输入输出样例 #2

输入 #2

110
1 2 3 4 5 6 7 8 9 10
3 2 1 2 3 4 5 6 7 8

输出 #2

2

说明/提示

样例说明

输入 #1

该组输入共有 3 3 3 个加速腔,依次能够提供的动能为 1 1 1 2 2 2 3 3 3。从第 1 1 1 个加速腔运行到第 2 2 2 个加速腔损失 2 2 2 动能,从第 2 2 2 个加速腔运行到第 3 3 3 个加速腔损失 3 3 3 动能,从第 3 3 3 个加速腔运行到第 1 1 1 个加速腔损失 4 4 4 动能。不管从哪个加速腔导入质子束,都会使得质子束在两个加速腔运行过程中动能变为零,无法环绕轨道一周。

输入 #2

该组输入共有 10 10 10 个加速腔,如果从第 1 1 1 个加速腔导入质子束,将获得动能 1 1 1,但是在从第 1 1 1 个加速腔运行到第 2 2 2 个加速腔的过程中会损失 3 3 3 动能,因此会使得质子束无法环绕轨道一周。而从第 2 2 2 个到第 10 10 10 个加速腔中的任意一个导入质子束,均能保证质子束在加速腔之间运行时动能不为零,因此都可作为导入质子束的加速腔,但编号为 2 2 2 的加速腔具有最小的编号。需要注意,从第 2 2 2 个加速腔导入质子束,当运行到第 3 3 3 个加速腔时,动能恰为零,根据题意,这种情形是允许的。


数据范围

  • Subtask 1 1 1 2 ≤ n ≤ 10 2 \le n \le 10 2n10 10 10 10 分。
  • Subtask 2 2 2 2 ≤ n ≤ 1 0 3 2 \le n \le 10^3 2n103 30 30 30 分。
  • Subtask 3 3 3 2 ≤ n ≤ 1 0 5 2 \le n \le 10^5 2n105 30 30 30 分。
  • Subtask 4 4 4 2 ≤ n ≤ 1 0 6 2 \le n \le 10^6 2n106 30 30 30 分。

对于 100 % 100\% 100% 的数据, 1 ≤ T ≤ 20 1 \le T \le 20 1T20 0 < e i ≤ 100 0 \lt e_i \le 100 0<ei100 0 < d i ≤ 100 0 \lt d_i \le 100 0<di100


约定

质子束的运行方向规定为:从第 1 1 1 个加速腔到第 2 2 2 个加速腔,从第 2 2 2 个加速腔到第 3 3 3 个加速腔 ⋯ \cdots 从第 n n n 个加速腔到第 1 1 1 个加速腔。

前缀和 单调双向队列 化环为链

a[i]= e[i%N]-d[i%N],a有2N个元素。preSum是a的前缀和。枚举结尾 i ∈ [ 0 , n ) i \in[0,n) i[0,n),求对应的最佳首下标 j ∈ [ 0 , i ] j\in[0,i] j[0,i]。如果有多个符合条件,则求最小j:
∀ i 1 ∈ [ j , i ] \forall i1 \in [j,i] i1[j,i],e[j…i1]都必须大于等于0。即preSum[i1+1]-preSum[j] >=0。如果preSum[j] > preSum[i+1],则j不是i及更大下标的解。
可永久删除(操作一)。j1<j2,如果preSum[j1] < preSum[j2],则j1一定劣于j2。如果j2是i的解,则j1也是,且j1更小。淘汰j2后(操作二),preSum[j]降序。
操作一:队首比较、出队。操作二:队尾判断是否需要入队,队尾入队。

代码

核心代码

#include <iostream>
#include <sstream>
#include <vector>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<string>
#include<algorithm>
#include<functional>
#include<queue>
#include <stack>
#include<iomanip>
#include<numeric>
#include <math.h>
#include <climits>
#include<assert.h>
#include<cstring>
#include<list>#include <bitset>
using namespace std;template<class T1, class T2>
std::istream& operator >> (std::istream& in, pair<T1, T2>& pr) {in >> pr.first >> pr.second;return in;
}template<class T1, class T2, class T3 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3>& t) {in >> get<0>(t) >> get<1>(t) >> get<2>(t);return in;
}template<class T1, class T2, class T3, class T4 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3, T4>& t) {in >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);return in;
}template<class T = int>
vector<T> Read() {int n;cin >> n;vector<T> ret(n);for (int i = 0; i < n; i++) {cin >> ret[i];}return ret;
}
template<class T = int>
vector<T> ReadNotNum() {vector<T> ret;T tmp;while (cin >> tmp) {ret.emplace_back(tmp);if ('\n' == cin.get()) { break; }}return ret;
}template<class T = int>
vector<T> Read(int n) {vector<T> ret(n);for (int i = 0; i < n; i++) {cin >> ret[i];}return ret;
}template<int N = 1'000'000>
class CInBuff
{
public:inline CInBuff() {}inline CInBuff<N>& operator>>(char& ch) {FileToBuf();ch = *S++;return *this;}inline CInBuff<N>& operator>>(int& val) {FileToBuf();int x(0), f(0);while (!isdigit(*S))f |= (*S++ == '-');while (isdigit(*S))x = (x << 1) + (x << 3) + (*S++ ^ 48);val = f ? -x : x; S++;//忽略空格换行		return *this;}inline CInBuff& operator>>(long long& val) {FileToBuf();long long x(0); int f(0);while (!isdigit(*S))f |= (*S++ == '-');while (isdigit(*S))x = (x << 1) + (x << 3) + (*S++ ^ 48);val = f ? -x : x; S++;//忽略空格换行return *this;}template<class T1, class T2>inline CInBuff& operator>>(pair<T1, T2>& val) {*this >> val.first >> val.second;return *this;}template<class T1, class T2, class T3>inline CInBuff& operator>>(tuple<T1, T2, T3>& val) {*this >> get<0>(val) >> get<1>(val) >> get<2>(val);return *this;}template<class T1, class T2, class T3, class T4>inline CInBuff& operator>>(tuple<T1, T2, T3, T4>& val) {*this >> get<0>(val) >> get<1>(val) >> get<2>(val) >> get<3>(val);return *this;}template<class T = int>inline CInBuff& operator>>(vector<T>& val) {int n;*this >> n;val.resize(n);for (int i = 0; i < n; i++) {*this >> val[i];}return *this;}template<class T = int>vector<T> Read(int n) {vector<T> ret(n);for (int i = 0; i < n; i++) {*this >> ret[i];}return ret;}template<class T = int>vector<T> Read() {vector<T> ret;*this >> ret;return ret;}
private:inline void FileToBuf() {const int canRead = m_iWritePos - (S - buffer);if (canRead >= 100) { return; }if (m_bFinish) { return; }for (int i = 0; i < canRead; i++){buffer[i] = S[i];//memcpy出错			}m_iWritePos = canRead;buffer[m_iWritePos] = 0;S = buffer;int readCnt = fread(buffer + m_iWritePos, 1, N - m_iWritePos, stdin);if (readCnt <= 0) { m_bFinish = true; return; }m_iWritePos += readCnt;buffer[m_iWritePos] = 0;S = buffer;}int m_iWritePos = 0; bool m_bFinish = false;char buffer[N + 10], * S = buffer;
};class Solution {
public:int Ans(const int N, vector<int>& e, vector<int>& d) {vector<int> preSum(2 * N + 1);for (int i = 0; i < 2 * N; i++) {preSum[i + 1] = preSum[i] + e[i % N] - d[i % N];}deque<int> que;for (int i = 0; i < 2 * N; i++) {while (que.empty() || (preSum[que.back()] > preSum[i])) {que.emplace_back(i);}while (que.size() && (preSum[que.front()] > preSum[i + 1])) {que.pop_front();}if (que.size() && (i + 1 - que.front() >= N)) {return que.front() + 1;}}return -1;}
};int main() {
#ifdef _DEBUGfreopen("a.in", "r", stdin);
#endif // DEBUG	ios::sync_with_stdio(0); cin.tie(nullptr);CInBuff<10'000'000> in;int T,N;	in >> T;for (int i = 0; i < T; i++){in >> N ;auto e  = in.Read<int>(N);auto d = in.Read<int>(N);
#ifdef _DEBUG		//printf("N=%d", N);//Out(e, "e=");//Out(d, "d=");//Out(B, "B=");//Out(strs2, ",strs2=");//Out(que, ",que=");/*Out(que, "que=");*/
#endif // DEBUG		auto res = Solution().Ans(N,e,d);cout << ((-1==res)?"Failed!" : to_string(res).c_str()) << "\n";}return 0;
}

单元测试

	int N ;vector<int> e, d;TEST_METHOD(TestMethod1){N=3,e = { 1,2,3 }, d = { 2,3,4 };auto res = Solution().Ans(N, e, d);AssertEx(-1, res);}TEST_METHOD(TestMethod2){N = 10,e = { 1,2,3,4,5,6,7,8,9,10 },d = { 3,2,1,2,3,4,5,6,7,8 };auto res = Solution().Ans(N, e, d);AssertEx(2, res);}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

http://www.dtcms.com/a/508725.html

相关文章:

  • 信阳做网站汉狮网络wordpress 微信发布文章
  • 昆明网站建站平台北京朝阳网站
  • 网站的程序有哪些内容电子商务平台的类型
  • Ubuntu 24.04 上安装 Sonatype Nexus Repository(Maven 私服)
  • 01_svm_二分类
  • 莱芜定制网站建设公司培训机构排名前十
  • 基于单片机的四沟道步进电机玉米补种机设计与实现
  • 网络安全设备:入侵检测系统(IDS)、入侵防御系统(IPS)的配置与使用
  • 阿里云 oss做网站吉林省住房建设保障厅网站
  • 鸿蒙Next Performance Analysis Kit:打造极致流畅的应用体验
  • SkyWalking运维实战指南:配置解析与日常运维全攻略
  • 网站建设目标初步目标wordpress多少钱一年
  • 济南网站搜索排名深圳知名网站设计公司排名
  • 最好的网站模板用树莓派做网站服务器好吗
  • Java 25 中的 6 个新特性解读
  • 力扣hot100做题整理91-100
  • 【FPGA】设计流程——仿真验证
  • 做黑彩网站图片脑叶公司
  • php网站建设实例最佳搜索引擎磁力吧
  • BearPi小熊派 鸿蒙入门开发笔记(4)
  • 做网站排名收益做网站主页上主要放哪些内容
  • 如何做网站流量买卖2017网站发展趋势
  • nvidia gr00t运行服务和客户端,以及模型微调的时候碰到模型无法下载的问题,解决方法是下载离线的模型,然后修改路径,nvidia gr00t模型微调
  • 网站建设费用贵不贵房屋和建设工程信息平台
  • 企业网站源码模板网站建设与维护方式
  • lora与模型的关系(小白入门了解)
  • xtuoj 公共的数
  • 删除西部数码网站管理助手嘟嘟嘟在线视频免费观看
  • 做网站要会写代码吗网站建设硬件投入表
  • 有官网建手机网站吗做自己域名的网站很贵吗