POJ2456

只要用到的算法有:

1. 贪心 2.二分 3 排序

代码如下:

#include <stdio.h>

#define MAX_NUM	100000

int g_N;
int g_C;

int g_loc[MAX_NUM];


void insertion_sort(int *a, int start, int end)
{
	int i, j;
	for(i = start + 1; i <= end; ++i)
	{
		int k = a[i];
		for( j = i - 1; (j >= start) && (a[j] > k); --j)
		{
			a[j+1] = a[j];
		}

		a[j+1] = k;
	}
}


int swap(int *a, int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

int median(int *a, int start, int end)
{
	int mid = (start + end) / 2;
	if( a[mid] < a[start] )
	{
		swap(&a[mid], &a[start]);
	}

	if(a[end] < a[start])
	{

		swap(&a[start], &a[end]);
	}

	if(a[end] < a[mid])
	{
		swap(&a[end], &a[mid]);
	}

	swap(&a[mid], &a[end -1]);

	return a[end -1];
}

void _quick_sort(int *a, int start, int end)
{
	if( start + 10 <= end)
	{
		int i, j;
		for(;;)
		{
			i = start, j = end - 1;
			int med = median(a, start, end);
			while(a[++i] < med) {};
			while(a[--j] > med) {};

			if( i < j)
			{
				swap( &a[i], &a[j]);
			}
			else
			{
				break;		
			}
		}
		
		swap(&a[i], &a[end - 1]);
		printf("i = %d\n", i);
		_quick_sort(a, start, i - 1);
		_quick_sort(a, i + 1, end);
	}
	else
	{
		insertion_sort(a, start, end);
	}
}


void quick_sort(int *a, int size)
{
	_quick_sort(a, 0, size - 1);
}


void read_data( void)
{
	scanf("%d %d", &g_N, &g_C);
	int i;
	for(i = 0; i < g_N; ++i)
	{
		scanf("%d", &g_loc[i]);
	}
}


int meet(int len)
{
	int last_p = 0;
	int i;
	for( i = 1; i < g_C; ++i)
	{
		int cur_p = last_p + 1;
		while( cur_p < g_N && g_loc[cur_p] - g_loc[last_p] < len)
		{
			++cur_p;
		}

		if( cur_p == g_N)
		{
			return 0;
		}	

		last_p = cur_p;
	}

	return 1;
}

/*
int get_partition(int *a, int start, int end)
{
	int i, j;
	int key = a[end];
	j = start - 1;
	for( i = start; i < end; ++i)
	{
		if(a[i] <= key)
		{
			j++;
			swap(&a[i], &a[j]);
		}
	}

	++j;
	swap(&a[j], &a[end]);
	return j;
}

quick_sort2(int *a, int start, int end)
{
	if( start < end )
	{
		int pivot = get_partition(a, start, end);
		quick_sort2(a, start, pivot - 1);
		quick_sort2(a, pivot + 1, end);
	}
}
*/
void solve(void)
{
	int low = 0, high = g_loc[g_N-1] - g_loc[0];
	int mid;
	while( low  + 1 < high)
	{
		mid = (low+high) /2;
		if(meet(mid))
		{
			low = mid;
		}
		else
		{
			high = mid;
		}
	}

	printf("%d\n", low);
}

int compare( const void *a, const void *b)
{return ( *(int*)a - *(int*)b);
}
//
int main(void)
{
	//freopen("input.txt", "r", stdin);
	read_data();
	quick_sort(g_loc, g_N);
	//qsort(g_loc, g_N, 4, compare);
	solve();
	return 0;	
}

需要注意的是,使用快速排序的时候,要有适当的优化,不然可能会超时。上面代码里面注释掉的排序是算法导论里面介绍的,会导致超时。

二分代码还可以写成如下的形式:

void solve(void)
{
	int low = 0, high = g_loc[g_N-1] +1; //- g_loc[0];
	int mid;
	int ans;
	while( low <= high)
	{
		mid = (low+high) >> 1;
		if(meet(mid))
		{
			low = mid + 1;
			ans = mid;
		}
		else
		{
			high = mid -1;
		}
	}

	printf("%d\n", ans);
}

或者:

void solve(void)
{
	int low = 0, high = g_loc[g_N-1] +1; //- g_loc[0];
	int mid;
	int ans;
	while( low <= high)
	{
		mid = (low+high) >> 1;
		if(meet(mid))
		{
			low = mid + 1;
			ans = mid;
		}
		else
		{
			high = mid -1;
		}
	}

	printf("%d\n", high );
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值