zoukankan      html  css  js  c++  java
  • CF1375E Solution

    题目链接

    题解

    将所有逆序对((x_i,y_i))按照(y_i)降序排序,若(y_i)相等则按(a_{x_i})((a)​为原序列)升序排序,若两者均相等则按(x_i)升序排序即可。

    对于序列(a),如果每次寻找一组逆序对并将它们交换,易得经过若干组操作后一定可以化为单调不降的序列,因此我们只需保证在交换原有逆序对过程中不产生新逆序对即可。考虑从后往前依次归位((y_i)降序),易得按(a_{x_i})升序排序的话,原先最小的(a_{x_i})到了次小的(a_{x_i})位置上,次小的则到了第三小的位置上,以此类推,而最大的到达了(y_i)上,(a_{y_i})到达了最小的(a_{x_i})的位置上。这样可以使([1,y_i])间最大的元素位于(y_i),完成归位,而其余的(a_{x_i})所在位置的元素则分别变小了一等。考虑其中一个(a_{x_i})([1,x_i))间大于(a_{x_i})的元素交换后仍大于(a_{x_i})​,逆序对不变。而((x_i,n])间小于(a_{x_i})的元素一定仍小于(a_{x_i}),因为交换后每一位(除去(a_{y_i})​不考虑)只是变小并未变大。不过,当(a_{x_i})中元素出现重复时,需要保证交换后最小的元素位于最前,也就是按(x_i)升序排序。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010; 
    struct node {int x,y;} inv[N*N];
    int a[N],n,cnt;
    bool cmp(node x,node y) {return x.y>y.y || (x.y==y.y && a[x.x]<a[y.x]) || (x.y==y.y && a[x.x]==a[y.x] && x.x<y.x);}
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	for(int i=1;i<=n;i++)
    		for(int j=i+1;j<=n;j++) 
    			if(a[j]<a[i]) inv[++cnt].x=i,inv[cnt].y=j;
    	sort(inv+1,inv+cnt+1,cmp);
    	for(int i=1;i<=cnt;i++) swap(a[inv[i].x],a[inv[i].y]);
    	bool flag=0;
    	for(int i=1;i<=n;i++)
    		if(a[i]<a[i-1] && i>1) {flag=1; break;}
    	if(flag) {printf("-1"); return 0;}
    	printf("%d
    ",cnt);
    	for(int i=1;i<=cnt;i++) printf("%d %d
    ",inv[i].x,inv[i].y);
    	return 0;
    }
    
  • 相关阅读:
    python实用技巧总结(二)
    python实用技巧总结(一)
    windows下tensorflow/objectdetection API(SSD)环境搭建(基于tensorflow1.14和python3.6)
    理解Python函数和方法
    理解迭代器和可迭代对象
    Anaconda安装报错
    Windows下命令行Git无法显示中文问题解决方案
    web服务器/HTTP协议基础
    Unity3D第三人称摄像机
    Ubuntu 18.04 安装 mysql
  • 原文地址:https://www.cnblogs.com/violetholmes/p/15131804.html
Copyright © 2011-2022 走看看