Codeforcces::GYM 102586F Robots

题目链接

题目大意

n n n 个机器人和 n n n 个天线,分布在直线上,坐标各不相同。如果我们激活某一条天线,那么离它最近的机器人会移动到天线处爆炸,而其他机器人不动。如果两个机器人和天线距离相同,那么左侧的机器人移动。需要构造一个激活顺序,让机器人移动的距离之和尽可能小,输出距离之和与激活顺序。保证输入机器人和天线坐标分别递增

解题思路

显然,从左到右,让机器人和天线一一对应,机器人的移动总距离是最小的。
那么,如何构造顺序让机器人和天线正好可以一一对应呢?首先可以考虑最左侧的天线。如果最左侧的天线,左侧没有机器人,那么激活它之后一定是最左侧的机器人会移动,激活它没有任何问题。如果最左侧的天线对应的机器人在它的左边,那么就把它暂存入栈,然后继续判断下一个。如果遇到一个天线,对应的机器人在它右边,那么结合栈顶元素,构成一种情况:中间两个天线,两侧是它们对应的机器人。那么至少有一个天线,激活后是可以吸引正确的机器人的。循环直至末尾,如果栈中还有剩余元素,那么一定可以从右向左依次输出(因为栈中保存的元素,都是机器人在对应天线的左侧)

参考代码
#include<bits/stdc++.h>
using namespace std;
int a[200010], b[200010];
int main(){
	int n;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
	}
	for(int i = 1; i <= n; i ++){
		cin >> b[i];
	}
	
	long long x = 0;
	for(int i = 1; i <= n; i ++)x += abs(a[i] - b[i]);
	cout << x << '\n';
	
	stack<int> s;
	for(int i = 1; i <= n; i ++){
		if(a[i] > b[i]){
			while(!s.empty() and b[s.top()] - a[s.top()] <= a[i] - b[s.top()]){
				cout << s.top() << ' ';
				s.pop(); 
			}
			cout << i << ' ';
		}
		else{
			s.push(i);
		}
	}
	while(!s.empty()){
		cout << s.top() << ' ';
		s.pop(); 
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值