• 题解-CF1375E Inversion SwapSort


    CF1375E Inversion SwapSort

    给定长度为 (n) 的序列 (a_i),求一种将每个逆序对下标 ((u,v)) 的排序,使依次交换每个 ((a_u,a_v)) 后,(a_i) 不减。

    数据范围:(1le nle 1000)(1le a_ile 10^9)


    很明显我的脑子被瘟化课搞残了,这整场的思维题,做出三道就脑子爆出弹簧了。于是只做出 (3) 题,扣了 (95) 分。

    于是我奋发图强,决定写这篇题解,并全面改名为 ( t CF) 账号的名字 ( t George1123)。废话不多说。


    这题的 (a_i) 不是互不相同的,但是为了简化问题,就当它是一个排列。

    因为最后 (a_i) 不减,所以最终每个下标 要放 现在哪个下标的数 是固定的,设最终 (i) 处要放现在的 (a_{b_i})

    (n=5)(a_i)5 3 4 1 2(b_i)4 5 2 3 1

    交换了 (a_{b_u})(a_{b_v}) 后,(b_u)(b_v) 交换。当 (a_i) 有序时,(b_i) 也有序;(b_i) 有序时,(a_i) 也有序。

    对于 (a_i) 中的逆序对 ((b_u,b_v))

    因为 (b_u<b_v)(a_{b_u}>a_{b_v}),所以 (b_v>b_u)(v<u)

    考虑对 (b_i) 做冒泡排序,所以 (b_i>b_{i+1})((b_i,b_{i+1})) 会被交换。

    因为最终 (b_i) 会有序,所以每个 (b_v>b_u)(v<u)((b_u,b_v)) 都会被交换,(a_i) 会有序。

    把每个 (b_i>b_{i+1})((b_{i+1},b_i)) 记录下来就是答案。

    同理,在 (a_i) 互有相同时,若有 (a_{b_u}=a_{b_v}(u<v)),令 (b_u<b_v) 可以防止答案中出现非逆序对。


    • 代码
    //Main
    int main(){
    	int n; cin>>n;
    	vector<int> a(n),o(n);
    	for(int i=0;i<n;i++) cin>>a[i];
    	iota(b(o),e(o),0);
    	sort(b(o),e(o),[&](int p,int q){
    	return a[p]==a[q]?p<q:a[p]<a[q];});
    	vector<pair<int,int>> ans;
    	for(int t=0;t<n;t++)
    		for(int i=0;i<n-1;i++)
    			if(o[i]>o[i+1]) ans.pb(mp(o[i+1],o[i])),swap(o[i],o[i+1]);
    	cout<<sz(ans)<<'
    ';
    	for(auto p:ans) cout<<p.x+1<<' '<<p.y+1<<'
    ';	
    	return 0;
    }
    

    祝大家学习愉快!

  • 相关阅读:
    React 不暴露webpack配置的情况下,修改webpack配置
    Array的一些方法
    ES 6 学习
    位运算解决“一个数组中,只有一个数字出现n次,其他数字出现k次”问题
    句子反转——牛客刷题(java)
    数串——牛客刷题
    链表分割——牛客剑指offer
    合并两个排序链表——牛客offer
    复杂链表的复制——牛客offer
    两个链表的第一个公共结点——牛客offer
  • 原文地址:https://www.cnblogs.com/George1123/p/13245888.html
Copyright © 2020-2023  润新知