列表

详情


NC53186. 冒泡排序

描述

冒泡排序是一种能对数列进行排序的算法。在使用冒泡排序对长为N的数列A进行升序排序时,如果相邻两个数中左边的数大于了右边的数,则交换这两个数的位置。每次从数列的前端开始扫描,当,就将这两个数交换。扫描进行N-1次后,数列就一定满足升序排列。
对数列A进行冒泡排序的交换次数表示:对数列A进行以上所述算法时,整数被交换的次数。(冒泡排序的算法和实现包括循环顺序、范围和终止条件等。有时会存在细微差别。但是,当应用于相同的数列时,整数的交换次数不会因这些情况的不同而改变。)
例如,以下为对长为N的整数数列A进行冒泡排序的程序(C语言)。
void bubble_sort(int *a, int n) {     int i, j;     for (i = 0; i < n - 1; ++i)     {         for (j = 0; j < n - 1; ++j)         {             if (a[j] > a[j + 1])             {                 /* 以下 3 行相当于一次整数交换 */                 int x = a[j];                 a[j] = a[j + 1];                 a[j + 1] = x;             }         }     } }

任务
给出长为N的数列A,对数列A中任意两个整数进行一次交换得到数列A'。请编写程序求出对数列A'使用冒泡排序使其升序排列的交换次数的最小值。(请注意:开始时对数列A中整数的交换并不需要交换相邻两个数。)

输入描述

第一行为一个整数N,表示数列A的长度;接下来的N行中的第i行为一个整数A_i,表示数列A中第i个整数。

输出描述

输出一行一个整数:表示对数列A'进行冒泡排序的交换次数的最小值。

示例1

输入:

5
10
3
6
8
1

输出:

0

说明:

将数列A开头的10和最后的1交换,数列A'就已经是升序的了。冒泡排序的交换次数为0。

示例2

输入:

5
3
1
7
9
5

输出:

2

说明:

将数列A第3个数7和最后一个数5交换,数列A'就成了3,1,5,9,7。A'的冒泡排序交换次数为2。

示例3

输入:

3
1
2
3

输出:

1

说明:

虽然一开始数列A就是升序排列的,但是还是必须交换其中两个数构成数列A'。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 79ms, 内存消耗: 12388K, 提交时间: 2023-01-07 16:31:30

#include<bits/stdc++.h>
using namespace std;
namespace IO{
	template<typename T>inline bool read(T &x){
		x=0;
		char ch=getchar();
		bool flag=0,ret=0;
		while(ch<'0'||ch>'9') flag=flag||(ch=='-'),ch=getchar();
		while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(),ret=1;
		x=flag?-x:x;
        return ret;
	}
	template<typename T,typename ...Args>inline bool read(T& a,Args& ...args){
	    return read(a)&&read(args...);
	}
	template<typename T>void prt(T x){
		if(x>9) prt(x/10);
		putchar(x%10+'0');
	}
	template<typename T>inline void put(T x){
		if(x<0) putchar('-'),x=-x;
		prt(x);
	}
	template<typename T>inline void put(char ch,T x){
		if(x<0) putchar('-'),x=-x;
		prt(x);
		putchar(ch);
	}
	template<typename T,typename ...Args>inline void put(T a,Args ...args){
	    put(a);
		put(args...);
	}
	template<typename T,typename ...Args>inline void put(const char ch,T a,Args ...args){
	    put(ch,a);
		put(ch,args...);
	}
	inline void put(string s){
		for(int i=0,sz=s.length();i<sz;i++) putchar(s[i]);
	}
	inline void put(const char* s){
		for(int i=0,sz=strlen(s);i<sz;i++) putchar(s[i]);
	}
}
using namespace IO;
#define N 300005
#define ll long long
int n,w[N],b[N],m,posl[N],posr[N],vall[N],valr[N],tl,tr;
template<typename T>struct BIT{
	#define lowbit(x) (x&-x)
	T c[N];
	inline void update(int x,T v){
		for(;x<=m;x+=lowbit(x)) c[x]+=v;
	}
	inline T query(int x){
		T res=0;
		for(;x;x^=lowbit(x)) res+=c[x];
		return res;
	}
	#undef lowbit
};
BIT<int> B;
template<typename T>struct Segment{
	T t[N<<2],lz[N<<2];
	#define lc(x) (x<<1)
	#define rc(x) (x<<1|1)
	inline void push_up(int x){
		t[x]=max(t[lc(x)],t[rc(x)]);
	}
	inline void push_down(int x){
		if(!lz[x]) return;
		t[lc(x)]+=lz[x],t[rc(x)]+=lz[x];
		lz[lc(x)]+=lz[x],lz[rc(x)]+=lz[x];
		lz[x]=0;
	}
	inline void update(int x,int l,int r,int ql,int qr,T val){
		if(ql<=l&&qr>=r) return t[x]+=val,lz[x]+=val,void();
		push_down(x);
		int mid=l+r>>1;
		if(ql<=mid) update(lc(x),l,mid,ql,qr,val);
		if(qr>mid) update(rc(x),mid+1,r,ql,qr,val);
		push_up(x);
	}
	#undef lc
	#undef rc
};
Segment<ll> T;
ll ans=2e18,sum;
struct Line{
	int l,r,val;
	Line(int _l=0,int _r=0,int _val=0):l(_l),r(_r),val(_val){}
};
vector<Line> g[N];
int main(){
	read(n);
	for(int i=1;i<=n;i++) read(w[i]),b[i]=w[i];
	sort(b+1,b+n+1),m=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=n;i++) w[i]=lower_bound(b+1,b+m+1,w[i])-b; 
	for(int i=1;i<=n;i++)
		sum+=B.query(m)-B.query(w[i]),B.update(w[i],1);
	if(!sum) return puts(m!=n?"0":"1"),0;
	for(int i=1;i<=n;i++)
		if(!tl||w[i]>vall[tl]) posl[++tl]=i,vall[tl]=w[i];
	for(int i=n;i;i--)
		if(!tr||w[i]<valr[tr]) posr[++tr]=i,valr[tr]=w[i];
	reverse(posr+1,posr+tr+1),reverse(valr+1,valr+tr+1);
	for(int i=1;i<=n;i++){
		int lx=lower_bound(vall+1,vall+tl+1,w[i])-vall;
		int ly=lower_bound(posl+1,posl+tl+1,i)-posl-1;
		int rx=upper_bound(posr+1,posr+tr+1,i)-posr;
		int ry=upper_bound(valr+1,valr+tr+1,w[i])-valr-1;
		if(lx>ly||rx>ry) continue;
		if(vall[lx]==w[i]&&valr[ry]==w[i]){
			g[lx].emplace_back(rx,ry-1,1);
			g[lx+1].emplace_back(rx,ry-1,-1); 
			g[lx+1].emplace_back(ry,ry,1);
			g[ly+1].emplace_back(ry,ry,-1);
			lx++,ry--;
		}else if(vall[lx]==w[i]){
			g[lx].emplace_back(rx,ry,1);
			g[lx+1].emplace_back(rx,ry,-1);
			lx++;
		}else if(valr[ry]==w[i]){
			g[lx].emplace_back(ry,ry,1);
			g[ly+1].emplace_back(ry,ry,-1);
			ry--;
		}
		if(lx<=ly&&rx<=ry)
			g[lx].emplace_back(rx,ry,2),
			g[ly+1].emplace_back(rx,ry,-2);
	}
	for(int i=1;i<=tl;i++){
		for(auto tmp:g[i]) T.update(1,1,tr,tmp.l,tmp.r,tmp.val);
		ans=min(ans,sum-T.t[1]-1);
	}
	put('\n',ans);
	return 0;
}

上一题