uva 10706 Number Sequence

本文介绍了一种结合二分法与动态规划技术解决特定字符串问题的方法。通过对输入数据进行预处理,利用动态规划生成辅助数组,并通过二分查找定位字符串中的指定字符。适用于处理大规模数据集。

这道题目有点麻烦,首先用二分法找到第i个位置在Si的哪一个里面,所以要生成长度的辅助数组arr和length,用动态规划的方法生成是很简单的,因为输入的i有限,可以测试出来Si最多到31268项,算出来i是哪个si里面的第多少个位置(就是程序里面func函数算出来的i)就容易了,首先在初始化的时候初始化字符数组S1S2S3.......S31268,在里面取a[i]打印出来就行了。

#include <stdio.h>
#include <string.h>

#define		MAX_LENGTH		31300

long long arr[MAX_LENGTH+1];
long long length[MAX_LENGTH+1];
char a[MAX_LENGTH*5];

void init_length()
{
	int i, start;
	char buf[10];
	arr[1] = 1;
	

	a[1] = '1';
	start = 2;
	for(i=2; i<MAX_LENGTH; i++)
	{

		sprintf(buf, "%d", i);
		memcpy(a+start, buf, strlen(buf));
		start += strlen(buf);


		if(i>=1 && i<=9)
		{
			arr[i] = arr[i-1] + 1;
			continue;
		}

		if(i>=10 && i<=99)
		{
			arr[i] = arr[i-1] + 2;
			continue;
		}

		if(i>=100 && i<=999)
		{
			arr[i] = arr[i-1] + 3;
			continue;
		}

		if(i>=1000 && i<=9999)
		{
			arr[i] = arr[i-1] + 4;
			continue;
		}

		if(i>=10000 && i<=99999)
		{
			arr[i] = arr[i-1] + 5;
			continue;
		}

		if(i>=100000 && i<=999999)
		{
			arr[i] = arr[i-1] + 6;
			continue;
		}

		
	}

	length[0] = 0;
	length[1] = arr[1];
	for(i=2; i<=MAX_LENGTH; i++)
	{
		length[i] = length[i-1] + arr[i];
		if(length[i] > 2147483647)
			break;
	}

	//printf("max i=%d value=%I64d\n", i, length[i]);
}

void func(long long index)
{
	int l, r, m;
	long long i;

	l = 0;
	r = 31268;

	while(1)
	{
		m = (l+r)/2;

		if(index>length[m-1] && index<=length[m])
			break;
		else if(index > length[m])
			l = m+1;
		else
			r = m-1;
	}

	i = index - length[m-1];
	printf("%c\n",a[i]);
}

int main(void)
{
	long long index;
	int n, i;

	//freopen("input.dat", "r", stdin);

	init_length();
	scanf("%d", &n);
	for(i=1; i<=n; i++)
	{
		scanf("%I64d", &index);
		func(index);
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值