[codeforces 1374F] Cyclic Shifts Sorting 按规则先排最小再排最大

Codeforces Round #653 (Div. 3)   参与排名人数11687

[codeforces 1374F]    Cyclic Shifts Sorting    按规则先排最小再排最大

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址http://codeforces.com/contest/1374/problem/F

ProblemLangVerdictTimeMemory
F - Cyclic Shifts Sorting GNU C++17Accepted46 ms4900 KB

题目大意:给定元素数量为n的数组a,可做如下操作[ai,ai+1,ai+2]变成[ai+2,ai,ai+1],问能否不超过n^2次操作,使数组a变成自小到大排列的数组。输出操作次数,即每次对应的数组脚标。若不能,输出-1.(反复读题,发现没有说输出最小次数,发现,只要次数不超过n^2即可。)

样例模拟如下:

5
5 4 3 2 1

6
3 1 3 2 2 3
位置3:5 4 (1 3 2)
位置1:(1 5 4) 3 2
位置3:1 5 (2 4 3)
位置2:1 (4 5 2) 3
位置2:1 (2 4 5) 3
位置3:1 2 (3 4 5)


8
8 4 5 2 3 6 7 3


13
2 1 1 6 4 2 4 3 3 4 4 6 6
位置2:8 (2 4 5) 3 6 7 3
位置1:(4 8 2) 5 3 6 7 3 
位置1:(2 4 8) 5 3 6 7 3
位置6:2 4 8 5 3 (3 6 7)
位置4:2 4 8 (3 5 3) 6 7
位置2:2 (3 4 8) 5 3 6 7
位置4:2 3 4 (3 8 5) 6 7
位置3:2 3 (8 4 3) 5 6 7
位置3:2 3 (3 8 4) 5 6 7
位置4:2 3 3 (5 8 4) 6 7
位置4:2 3 3 (4 5 8) 6 7
位置6:2 3 3 4 5 (7 8 6)
位置6:2 3 3 4 5 (6 7 8)



6
1 2 3 3 6 4

4
3 3 4 4
位置3:1 2 (6 3 3) 4
位置3:1 2 (3 6 3) 4
位置4:1 2 3 (4 6 3)
位置4:1 2 3 (3 4 6)

样例进一步模拟如下,大体思路,小的一定要排前头,大的一定要排后头。

5
5 4 3 2 1

让1排在第1位
5 4 (1 3 2)
(1 5 4) 3 2
让2排在第2位
1 5 (2 4 3)
1 (4 5 2) 3
1 (2 4 5) 3
让3排在第3位
1 2 (3 4 5)



8
8 4 5 2 3 6 7 3

让2排在第1位
8 (2 4 5) 3 6 7 3
(4 8 2) 5 3 6 7 3
(2 4 8) 5 3 6 7 3
让3排在第2位
2 4 (3 8 5) 6 7 3
2 (8 4 3) 5 6 7 3
2 (3 8 4) 5 6 7 3
让3排在第3位
2 3 8 4 5 (3 6 7)
2 3 8 (3 4 5) 6 7
2 3 (4 8 3) 5 6 7
2 3 (3 4 8) 5 6 7
4已排在第4位
让5排在第5位
2 3 3 4 (6 8 5) 7
2 3 3 4 (5 6 8) 7
6已排在第6位

最后两个数8 7处理不了

让8排在第8位
2 3 3 4 5 (7 6 8)
让7排在第7位
2 3 3 4 (6 5 7) 8
让6排在第6位
2 3 3 (5 4 6) 7 8
让5排在第5位
2 3 (4 3 5) 6 7 8
让3排在第3位
2 (3 3 4) 5 6 7 8

7
5 2 1 6 4 7 3

-1


6
1 2 3 3 6 4

让1排在第1位
1 2 3 3 6 4
让2排在第2位
1 2 3 3 6 4
让3排在第3位
1 2 3 3 6 4
让3排在第4位
1 2 3 3 6 4

最后两个数6 4处理不了
让6排在第6位
1 2 3 (4 3 6)
让4排在第5位
1 2 (3 3 4) 6

对应算法的样例输入输出数据如下:

Input:
5
5
1 2 3 4 5
5
5 4 3 2 1
8
8 4 5 2 3 6 7 3
7
5 2 1 6 4 7 3
6
1 2 3 3 6 4
Output:
0

6
3 1 3 2 2 3 
17
2 1 1 3 2 2 6 4 3 3 5 5 6 5 4 3 2 
-1
2
4 3 

AC代码如下:

#include <stdio.h>
int ans[252000],a[510],tot;
void move(int u){
	int t1,t2,t3;
	t1=a[u],t2=a[u+1],t3=a[u+2];
	a[u]=t3,a[u+1]=t1,a[u+2]=t2;
}
int main(){
	int t,n,i,j,mn,mx,u;
	scanf("%d",&t);
	while(t--){
		tot=0;
		scanf("%d",&n);
		for(i=1;i<=n;i++)scanf("%d",&a[i]);
		for(i=1;i<=n-2;i++){
			mn=1000;
			for(j=i;j<=n;j++)
				if(a[j]<mn)mn=a[j],u=j;//找区间[i,n]之间的最小值
			while(u>=i+2)ans[++tot]=u-2,move(u-2),u-=2;//最终u的落脚点要么在i,要么在i+1处。
			if(u==i+1)move(i),move(i),ans[++tot]=i,ans[++tot]=i;//u的落脚点在i+1处。
		}
		for(i=n;i>=3;i--){
			mx=-1;
			for(j=i;j>=1;j--)
				if(a[j]>mx)mx=a[j],u=j;
			while(u<=i-2)ans[++tot]=u,move(u),u+=2;//最终u的落脚点要么在i,要么在i-1处。
			if(u==i-1)move(i-2),ans[++tot]=i-2;//u的落脚点在i-1处。
		}
		for(i=1;i<n;i++)
			if(a[i]>a[i+1])tot=-1;
		if(tot==-1)printf("-1\n");
		else{
			printf("%d\n",tot);
			for(i=1;i<=tot;i++)printf("%d ",ans[i]);
			printf("\n");
		}
	}
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值