Sorting Device

Sorting Device

题目
After being stuck at home for months because of covid, you decided to explore the contents of your parent’s basement. Among numerous useless items, you found one peculiar object - a sorting device from the sixties that was used to teach sorting algorithms. The device consists of N ordered slots that get initialized with distinct integers once the device is turned on, and a screen for tracking cost. As a user, you can perform swap operations. One swap operation allows you to swap elements at positions i and j for a total cost of A∗|i−j|+B, where A,B are parameters written on the back of the device. Since you’ve been studying your sorting algorithms, you definitely know how to sort the numbers with the smallest possible cost. Right?

Input
The first line contains a single integer N (1≤N≤2⋅105 ) - the number of slots the machine has. The next line has N space-separated integers up to 109 in absolute value that the machine generated after you turned it on. The last line has two positive integers A,B from the machine specs. 1≤A,B≤1000.

Output
In the first line, output the smallest cost needed to sort the sequence. In the second line, output K - the number of swaps needed to do that. In the next K lines output the description of the swaps that need to be done. In each line output two numbers - indices of elements to be swapped, separated by a space. Indices start with one. If two or more sequences have the same total cost, you can output any of them.
大致题意:n个货物,给你n个数,要求交换后,按大小排列,交换i,j,位置的物品代价为A|I-J|+B 求最小代价,以及交换次数,和交换顺序*

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	ll n,A,B;
	cin>>n;
	vector<int> v(n);
	for(int i=0;i<n;i++) {
		cin>>v[i];
	}
	cin>>A>>B;
	vector<int> sx;
	sx=v;
	sort(sx.begin(),sx.end());
	sx.erase(unique(sx.begin(),sx.end()),sx.end());
	for(int i=0;i<n;i++){
		v[i]=lower_bound(sx.begin(), sx.end(),v[i]) - sx.begin();//在这里确定当前位置的物品应该放的位置
	}
	 ll cost = 0;
  vector<pair<int,int>>ans;
  auto swp = [&](int x, int y) {//交换函数
    cost += B + A*(y-x);
    ans.emplace_back(x+1, y+1);
    swap(v[x], v[y]);
  };
  for(int x=0;x<n;x++) 
  if(v[x] < x) {//应该向前跳
  //q中必是递增序列[v[x],x] ;
    vector<int> q ;
	q= {v[x]};
    while(v[q.back()] < x) q.push_back(v[q.back()]);//所谓存去的位置又要去哪 
    q.push_back(x);
    //如果不经过while循环直接交换(x,v[x]);
    //q保证了不会消耗多余的成本,相邻的代价小不会1->3->2反复
    reverse(q.begin(),q.end());//翻转,不翻转无法到达应该去的地方 
    for(int i=1;i<(int)(q).size();i++) swp(q[i], q[i-1]);
  }

  cout << cost << endl;
  cout << (int)(ans).size() << endl;
  int len=ans.size();
  for(int i = 0;i < len;i ++) printf("%d %d\n",ans[i].first,ans[i].second);
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值