HDU 1027 Ignatius and the Princess II 選擇序列題解

直接選擇序列的方法解本題,但是最壞時間效率是O(n*n),故此不能達到0MS。ios

使用刪除優化,那麼就可以達到0MS了。算法

刪除優化就是當需要刪除數組中的元素爲第一個元素的時候,那麼就直接移動數組的頭指針就可以了,那麼時間效率就是O(1)了,而普通的刪除那麼時間效率是O(n),故此大大優化了程序。數組

怎樣直接選擇第k個序列,可以參考本博客的Leetcode題解。Leetcode題有個如出一轍的題目。只是沒有使用刪除優化。函數


看見本題的討論中基本上都是使用STL解,還有沾沾自喜的傢伙,只是使用STL解決本題儘管是可以,但是那是因爲本題的數據很是弱;大數據

因爲使用STL的時間效率是O(n*m),當中n多是1000, 而m多是10000,故此會達到1千萬的數據處理,隨便添加個大數據用例就會超時。優化

故此使用STL來解決本題事實上是很是次,很是0基礎的解法了。spa


#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <limits.h>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;

const int MAX_N = 1001;
int arr[MAX_N], N, M, tbl[MAX_N];

void genSeqNum()
{
	int mth = M-1;
	memset(tbl, 0, sizeof(int) * N);
	tbl[N-1] = 0;
	for (int i = N-2, d = 2; i >= 0 && mth > 0; i--, d++)
	{
		tbl[i] = mth % d;
		mth /= d;
	}
}

void eraseNth(int A[], int i)
{
	--N;
	for (; i < N; i++)
	{
		A[i] = A[i+1];
	}
}

void printNums()
{
	genSeqNum();
	
	int *A = arr;
	printf("%d", A[tbl[0]]);
	if (!tbl[0]) A++, N--;
	else eraseNth(A, tbl[0]);	

	int t = 1;//定位tbl下標
	while (N > 0)//優化以後的算法
	{
		for (; N && !tbl[t]; t++)//主要優化地方
		{
			printf(" %d", *A);//輸出爲零的,不用使用刪除函數
			A++, N--;//又一次定位數列
		}
		if (!N) break;//已經輸出完成

		printf(" %d", A[tbl[t]]);//不爲零的選擇,使用刪除函數
		eraseNth(A, tbl[t]);
		t++;
	}
	putchar('\n');
}

int main()
{
	while (scanf("%d %d", &N, &M) != EOF)
	{
		for (int i = 0; i < N; i++)
		{
			arr[i] = i+1;
		}
		printNums();
	}
	return 0;
}
相關文章
相關標籤/搜索