ACM水题-Beautiful Sequence(AC,杂题,贪心思想?)

Beautiful Sequence

Time Limit:1000MS  Memory Limit:65536K
Total Submit:206 Accepted:28

Description

A sequence of numbers A[1], A[2], ..., A[N] is beautiful only if each number A[i] ≥ i ( 1 ≤ i ≤ n ). Given a sequence of numbers, your task is to turn it into beautiful sequence with minimal swap operations between adjacent numbers.

Input

The first line of input gives the number of cases, T. T test cases follow.
The first line of each test case contains one integer N, and the second line contains N positive numbers.
(1 ≤ N ≤ 20, 0 ≤ A[i] ≤ 30 )

Output

For each test case, output the minimal swap times in a line.
If the sequence can’t be turned into beautiful sequence, just output “ugly sequence”.

Sample Input

2
5
1 2 3 5 4
4
1 3 1 4

Sample Output

1
ugly sequence

Source

GDUT Monthly 2009.11, by lynncui

 

 

/*	------------------------------------------------------------------------------------------------
	第一次看到这一道题的时候,还真的木有什么想法,木有什么感觉,找不到切入点,一下子找不到北。
	对于这一些貌似找规律的题目,自己都不是很在行。想来想去,不知道为什么会联想到操作系统内存管理
	那块,联想到了“首先适配算法”、“最佳适配算法”,不过这些想法,貌似没有什么作用,而且还说明
	我的知识体系够混乱的。
	后来再想了几下,发现都没有什么思路,连可行方案也没有想到。然后,嗯,然后....拖延症就发作了....
	几乎每天手机网页都开着这一题的页面,但是没有看多少眼,而且就算看了,又是在自己的思路中打转。


	后来,今天在床上休息的时候睡不着,拿起手机,再看看这一道题,索性认真思考一下,拒绝拖延症,结果
	想到了可行方案~~自己果然是比较慢热的说~~~



	大概想法:
	
	输入:一个序列,a[1]....a[N]。
	初始化:首先,找到最后一个不符合beautiful条件,也就是不符合a[i]>=i的元素,保存其下标为nEroIndex
	
	保持:然后从nEroIndex递减开始找到第一个符合a[i]>=nEroIndex的元素,然后进行交换操作,从中记录交换的
		  次数。如果找不到这样的元素,也就是丑陋的序列,跳出循环,打印结果。

		  例如序列:8 2 3 2 7 
		  第一次操作后变成:2 3 2 8 7

	      交换操作进行的方向说一下:
	     下标nEroIndex以及之后的序列都符合beatiful的条件,所以nEroIndex下标之后的元素不用考虑,将错误
		 范围缩小到1-(nEroIndex-1)之内,估计叫做将错误传递吧,将一个不符合条件的元素向下标更小的传递,
	     因为要符合a[i]>=i,所以交换操作不可能向下标更大的方向进行。

	     第一次操作之后,要更新nEroIndex的值,这一部分见注释。然后再跳到“保持”这一步,继续交换。

    正确性:从最后一个不符合条件的元素逐渐向左进行交换操作,将不符合条件的序列范围不断缩少,直到找不到
	        一个a[i]>=nEroIndex或者i<1为止。

    其实就是有两个选择的问题,一个就是初始化步骤和更新nEroIndex找第一个不符合条件的元素还是最后一个不
	符合条件的元素?我选了最后一个。

	另外一个就是找最近的一个符合a[i]>=i的下标还是最远的一个呢?我选了最近一个。这里都用到了贪心思想,
	因为要求用最少步数,所以我从尽量小去动已经符合a[i]>=i这个条件的元素。

	不过,后来发现貌似选哪一个都没有影响,呵呵~~~


	状况:AC,0MS

	------------------------------------------------------------------------------------------------	*/




#include<stdio.h>

int a[24] ;

int main(void)
{
	int n = 0 ;
	int i = 0 ;
	int j = 0 ;
	int t = 0 ;
	int nEroIndex = 0 ;
	int fCan = 0 ; 
	int nSwapTimes = 0 ;
	int nTemp = 0 ;
	int nNoneEro = 1 ; 
	int nNextIndex = 0 ;
	
	scanf("%d",&t) ;
	
	while(t-- > 0)
	{
		fCan = 1 ; 
		nSwapTimes = 0 ;
		nEroIndex = 0 ;
		nNoneEro = 1 ;  
		nNextIndex = 0 ;
		
		scanf("%d",&n) ;
		
		for(i = 1 ; i <= n ; ++i)
		{
			scanf("%d",&a[i]) ;
			
			if(a[i] < i)
			{
				nEroIndex = i ;
				fCan = 0 ;
			}
		}	
		for(i = nEroIndex ; i >= 1 ; --i)
		{
			if(a[i] >= nEroIndex)
			{
				fCan = 1 ; 
				nTemp = a[i] ; 
				
				for(j = i ; j < nEroIndex ; ++j)
				{
					a[j] = a[j+1] ;
					nSwapTimes++ ;
				}
				a[nEroIndex] = nTemp ;
				nEroIndex-- ;
				
				if(a[nEroIndex] >= nEroIndex)
				{
					nNoneEro = 1 ; 
					nNextIndex = nEroIndex ; 
					for(j = 1 ; j <= nNextIndex ; ++j)
					{					
						if(a[j] < j)
						{
							nEroIndex = j ;
							nNoneEro = 0 ; 
							fCan = 0 ;
						}
					}	
					if(1 == nNoneEro)
					{
						fCan = 1 ; 
						break ;
					}
					else
					{
						i = nEroIndex+1 ;
						fCan = 0 ;
					}		
				}
				else
				{
					i = nEroIndex+1 ;
					fCan = 0 ; 
				}
			}
		}
		if(1 == fCan)
		{
			printf("%d\n",nSwapTimes) ;
		}
		else
		{
			puts("ugly sequence") ;
		}
	}	
	return 0 ;
}


 

你可能感兴趣的:(Integer,input,each,output,联想,Numbers)