基础物理实验(困难版)

巧了我就是萌 提交于 2020-12-12 23:45:38

题目描述

《基础物理实验》是一门精品好课,手残的 JJLeo 需要做 nn 个不同的实验,将其编号为 1,2,,n1,2,⋯,n,它们的难度严格递增。

现在,智能化的选课网站帮他选择了一个做实验的顺序 [p1,p2,,pn][p1,p2,⋯,pn],其中 pipi 表示第 ii 次做的实验的编号。因为每个实验只需要做一次,且所有实验都必须做,所以 [p1,p2,,pn][p1,p2,⋯,pn]  11  nn 中每个整数都恰好出现了一次。

做实验应该循序渐进,因此 JJLeo 希望他做实验的难度可以严格递增,即满足 [p1,p2,,pn]=[1,2,,n][p1,p2,⋯,pn]=[1,2,⋯,n]。针对这种诉求,人性化的选课网站提供了一种更换实验顺序的方案,每个同学可以进行如下操作任意次:

  • 选择一个正整数 ii 满足 1<i<n1<i<n  pi1>pi>pi+1pi−1>pi>pi+1,将 [p1,,pi1,pi,pi+1,,pn][p1,⋯,pi−1,pi,pi+1,⋯,pn] 更改为 [p1,,pi+1,pi,pi1,,pn][p1,⋯,pi+1,pi,pi−1,⋯,pn]

现在 JJLeo 想求助于你,能否进行合适的操作来更换实验顺序,实现他的目标;如果可以,最少需要多少次操作。

输入

第一行为数据组数 tt (1t1001≤t≤100)。

对于每组数据,第一行一个正整数 nn (3n10003≤n≤1000),表示 JJLeo 要做的物理实验的数量。

第二行 nn 个以空格分隔的正整数 pipi (1pin1≤pi≤n),表示选课网站帮 JJLeo 选择的做实验的顺序 [p1,p2,,pn][p1,p2,⋯,pn],保证 [p1,p2,,pn][p1,p2,⋯,pn]  11  nn 中每个整数都恰好出现了一次。

输出

对于每组数据,输出一行,一个整数,如果该组数据可以通过合适的操作实现 JJLeo 的目标,输出最少需要操作的次数;否则,输出 1−1

输入样例

2
3
3 2 1
3
1 3 2

输出样例

1
-1

样例解释

对于第一组数据,选择 i=2i=2 并交换 p1p1  p3p3,序列变成 [1,2,3][1,2,3],只需一次操作即可满足要求。

对于第二组数据,无论如何选择 ii 进行操作,序列都无法变成 [1,2,3][1,2,3],故输出 1−1

AUTHOR:JJLeoc

#include <stdio.h>

int main() 
{
	int t,a[1050],i,j,n,x=0,y=0,flag=0;
	scanf("%d",&t);
	while(t--)
	{
		flag=0;
		x=0;
		y=0;
		scanf("%d",&n);
		for(i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			if((a[i]-i)&1)
				flag=-1;
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<i;j++)
			{
				if(a[j]>a[i])
					x++;
			}
		}
		for(i=1;i<=n;i+=2)
		{
			for(j=1;j<i;j+=2)
			{
				if(a[j]>a[i])
					y++;	
			}
		}		
		for(i=2;i<=n;i+=2)
		{
			for(j=2;j<i;j+=2)
			{
				if(a[j]>a[i])
					y++;	
			}
		}		
		if(y*3==x&&flag==0)
			printf("%d\n",y);
		else
			printf("-1\n"); 
	}
	return 0;
}

 

 考虑逆序对,总体的逆序对,每交换一次,整个序列的逆序对-3,奇数或偶数位上的逆序对-1,要使得,整个序列的逆序对为0 也就是,奇数和偶数位上的逆序对分别为0 ,那么整个数列的逆序对的三倍=奇数或偶数位上的逆序对,那么一定可以 交换到单增序列。以及,奇数位上偶数位上分别必须是奇数和偶数。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!