【主题】题目描述:
给你一个长度为n的数组。 w先生一次可以选一个数。 执行以下操作。
继续把这个数和右边的数交换。
如果右侧没有数量或右侧的数量大于该数量,请停止操作。
例如,序列14325在操作4时为13245。
为了使这个数组按升序排列,最少需要几次操作。
输入格式:
第一行包含正整数n。
第2行的n个,从左向右记述规定的排列。
输出格式:
输出一个数来表示答案。
样例数据:
输入
5
3 2 5 1 4
输出功率
3
备注:
示例说明:
依次选择5、2、3。
数据规模和承诺:
对于30%的数据,为n100。
对于50%的数据,为n1000。
对于100%的数据,为n1000000。
【分析】乍一看,这个问题似乎不那么顺利。 另外,数据范围也很广。 我们考虑用O(n logn)或O(n)的时间复杂度解决像1e 6这样大的n
(反正我不会告诉你我用暴力拿的50分)
首先,如果一个数只能向右移动,那么在其右边有比它小的数时,必然会再次操作它
这样的话,问题就简单了。 这个数(设为a[i]。 )右边的数中,最小的数为一个数) minn。 那么,minna[i]的时候,答案会增加一个。 否则,答案不会改变
33558 www.Sina.com/# include cstdio # include cstring # includealgorithmusingnamespacestd; const int N=1e 6 5; 常数int oo=2e 9; int a[N]; int main ()//Freopen ) ' sort.in ',' r ',stdin ); //Freopen(sort.out )、(w )、stdout; int n,I,s=0,minn=oo; scanf('%d ',n ); for(I=1; i=n; I ) scanf('%d ',a[i]; for(I=n; i=1; -I () if(minna[I] ) s; minn=min(minn,a[i]; }printf('%d ',s ); //fclose(stdin ); //fclose(stdout ); 返回0; }