序列算法题,包括和序列求解等

首先,说明一下,很长时间没来写博客了,是的,前段时间忙考研,耽误了半年多,现在,考研初试成绩出来了,现在正准备复试,由于不冲突,我就在准备c/c++的复试,顺便写写自己的技术blog。我一直这样认为,写blog可以加深自己对知识的理解。言罢,今天写了来两个小算法,算是熟悉一下语言的应用。

 

 

关于和序列问题,即形如(数据不重复)

10=1+2+3+4

10=1+2+7

10=1+3+6

10=1+4+5

10=1+9

10=2+3+5

10=2+8

10=3+7

10=4+6

 

const int N = 10;	/* test number  */

/* print the numbers  */
void print(int *list, int num)
{
	int i;
	cout<<N<<"="<<list[0];
	for(i = 1; i < num; i ++)
		cout<<"+"<<list[i];
	cout<<endl;
}

/* key function here  */
void getNumList(int sum, int begin,int *list ,int i)
{
	int next;

	list[i] = begin;
	i++;
	sum -= begin;
	if(sum == 0) print(list,i);// be found
	else
	{
		//continue searching the next number
		for(next = begin+1; next <= sum; next++)
			getNumList(sum,next,list,i);
	}
}


int main(void)
{
	int sum = N, begin;
	int list[N/2];

	/* test all beginings  */
	for(begin = 1; begin <= sum/2; begin ++)
		getNumList(sum,begin,list,0);
	return 0;
}

 

 很容易理解,不错解释。

 

还有一道很老的腾讯面试题,类似题型:

 

 写道
上个星期去腾讯面试一位主考官出的动脑题,当时被难住了,自己确实笨死了,麻烦高手帮解答下具体的计算思路。
题目如下:
给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数
要求下排每个数都是先前上排那十个数在下排出现的次数。
上排的十个数如下:
【0,1,2,3,4,5,6,7,8,9】

 例如:写道

 

####################
数值:0,1,2,3,4,5,6,7,8,9
分配:6,2,1,0,0,0,1,0,0,0
比如说,
0的下面我填写6,就表示在下面一共有6个0.
1的下面我填写2,表示下面下面一共有2个1
2的下面我填写1,表示下面下面一共有1个2

 

算法如下:

 

const int N = 10;
const int s[N] = {0,1,2,3,4,5,6,7,8,9};

/* repair the result list  */
void repair(int *array)
{
	int sum = 0;
	for(int i = 1; i < N; i++)
		sum += array[i];
	array[0] = N - sum;
}
/* test the result list */

int isRight(int *r)
{
	int i,j,sum;
    for(i = 0; i < N; i++)
	{
		sum = 0;
		//test the i number
		for(j = 0; j < N; j++)
			if(r[j] == s[i]) sum ++;
		if(sum != r[i])//not match
			return 0;
	}
	return 1;
}
/* print the right result list  */
void print(int *array)
{
	int i = 0;
	for(; i < N; i++) cout<<array[i]<<" ";
	cout<<endl;
}
/* 
 * key function  
 * serach from N to 0
 * constrict 1
 */
void getSerial(int sum, int *result, int num)
{
	int i;
	/* case 1*/
	if(num == 0 && sum != 0) return;
					// not match here
	/* case 2*/
	if(sum == 0)	// out of use
	{
		for(i = num; i > 0; i--) result[i] = 0;
		// important point for result[0]:constrict 2
		repair(result);
		if(isRight(result)) //constrict 3
		{
			print(result);
			return;
		}
		else return;
	}
	/* case 3*/
	for(i = 0;i*s[num] <= sum; i++)
	{
		result[num] = i;
		getSerial(sum-i*s[num],result,num-1);
	}
}

 

 可以注意到 该序列有三个限制条件(程序中也用constrict表示出来)

constrict 1: 就是两数组对乘的结果是N

    由于该条件限制较强,好理解,所以用作循环条件,以便减少遍历次数

constrict 2:repair()修正0的个数(比较特殊)待改善

constrict 3:就是检验是s【】中个数是否和人r【】中的对应(最强限制,但最难利用理解)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值