Cod sursa(job #72714)

Utilizator scapryConstantin Berzan scapry Data 15 iulie 2007 09:33:09
Problema Secv Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <assert.h>
#include <stdio.h>
#include <string.h>

enum { maxn = 5001, inf = 0x3f3f3f3f };

int n;
int t[maxn];

int num[maxn]; //sorted
int who[maxn]; //initial pos
int trans[maxn]; //transforming to 1, 2, 3, ...

int prev[maxn];
int ans;

void qsort(int begin, int end)
//num[], who[]
{
	assert(0 <= begin);
	assert(begin < end);
	assert(end < n);

	int i = begin, j = end, x = num[(i + j) / 2], tmp;

	while(true)
	{
		while(i <= j && num[i] < x)
			i++;
		while(j >= i && num[j] > x)
			j--;

		if(i > j)
			break;

		tmp = num[i];
		num[i] = num[j];
		num[j] = tmp;

		tmp = who[i];
		who[i] = who[j];
		who[j] = tmp;

		i++;
		j--;
	}

	if(begin < j)
		qsort(begin, j);
	if(i < end)
		qsort(i, end);
}

void adjust()
{
	int i, start;

	memcpy(num, t, sizeof(t));

	for(i = 0; i < n; i++)
		who[i] = i;

	qsort(0, n - 1);

	//transform
	start = 1;
	trans[0] = 1;
	for(i = 1; i < n; i++)
	{
		if(num[i] == num[i - 1])
			trans[i] = trans[i - 1];
		else
		{
			start++;
			trans[i] = start;
		}
	}

	for(i = 0; i < n; i++)
	{
		num[i] = trans[i];
		t[ who[i] ] = trans[i];
	}
}

void go()
{
	int i, j, tmp;

	if(n < 2) //blimey
	{
		ans = n;
		return;
	}

	adjust();

	ans = inf;
	for(i = 0; i < n; i++)
	{
		if(t[i] == 1) //smallest
		{
			prev[i] = i;
		}
		else
		{
			prev[i] = -1; //none 

			for(j = i - 1; j >= 0; j--) //MBO
				if(t[j] == t[i] - 1) //previous
					if(prev[j] != -1)
					{
						prev[i] = prev[j];
						break; //first is best (closest)
					}
		}

		if(t[i] == num[n - 1] && prev[i] != -1) //biggest
		{
			tmp = i - prev[i] + 1;

			if(tmp < ans)
				ans = tmp;
		}
	}

	if(ans == inf)
		ans = -1;
}

int main()
{
	int i;
	FILE *f = fopen("secv.in", "r");
	if(!f) return 1;

	fscanf(f, "%d", &n);
	for(i = 0; i < n; i++)
		fscanf(f, "%d", &t[i]);
	
	fclose(f);
	f = fopen("secv.out", "w");
	if(!f) return 1;

	go();

	fprintf(f, "%d\n", ans);
	fclose(f);
	return 0;
}