上升数列的生成算法
来源:互联网 发布:unity3d中文论坛 编辑:程序博客网 时间:2024/06/07 03:30
上升数列的生成算法
Martin Garder在《矩阵博士的魔法数》一书中给出了如下一个问题:
在12356789之间插入若干个加、减符号,使得其结果正好等于100。请找出问题全部的解。
任何两个相邻数之间可以插入+、-运算符之一,也可以不插入任何运算符。对于后一种特殊情况,我们引入一个特殊操作符$,a$b表示a、b之间不插入+、-操作符,其定义为
a$b = 10a+b
$运算满足结合律
a$(b$c)=(a$b)$c
因此多个$运算按从左至右、从右至左或其它次序将得到相同的结果。$运算的优先级比+、-运算高,且不满足交换律。
由上述定义,一个上升数列的运算式
123+4-5+6-78+9
可以表示成
1$2$3+4-5+6-7$8+9
的形式,而任何在上升数列中插入+、-运算符的算式都可以表示成下面的标准形式
1 op0 2 op1 3 op2 4 op3 5 op4 6 op5 7 op6 8 op7 9
这里opi为+、-、$之一。
~~~~~~~~~~~~~~~~~~~~~~~~~~
下面的程序枚举op0,…,op7的各种可能情形,找出运算结果等于100的表达式。由于运算会超过一个整数的表达范围,因此初始数据及中间结果均采用长整数表示。计算按从左至右的次序进行, 并考虑到$与+、-之间优先级的差异。
// File: IncSeq.C
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
struct LongIntList
{
long int val;
struct LongIntList *next;
};
struct OpList
{
int op;
struct OpList *next;
};
long int Result;
FILE *fp;
// Function prototypes
long int calc(long int num1, int op, long int num2);
void write_express(int *op,long int res);
int main(void)
{
struct LongIntList *numlist, *num, *num1, *num2;
struct OpList *oplist, *oprand, *oprand1, *oprand2;
int i;
int op[8];
long int res = 0;
if ((fp = fopen("inc.dat", "w")) == NULL)
{
printf("/nCan't creat file inc.dat!/n");
return 0;
}
printf("Please input the number you want to get:");
scanf("%ld", &Result);
for (op[0] = 0; op[0] < 3; op[0]++)
for (op[1] = 0; op[1] < 3; op[1]++)
for (op[2] = 0; op[2] < 3; op[2]++)
for (op[3] = 0; op[3] < 3; op[3]++)
for (op[4] = 0; op[4] < 3; op[4]++)
for (op[5] = 0; op[5] < 3; op[5]++)
for (op[6] = 0; op[6] < 3; op[6]++)
for (op[7] = 0; op[7] < 3; op[7]++)
{
oplist = NULL;
for (i = 7; i >= 0; i--)
{
oprand = (struct OpList *)malloc(sizeof(struct OpList));
oprand->op = op[i];
oprand->next = oplist;
oplist = oprand;
}
numlist = NULL;
for (i = 9; i > 0; i--)
{
num = (struct LongIntList *)malloc(sizeof(struct LongIntList));
num->val = (long)i;
num->next = numlist;
numlist = num;
}
oprand1 = oplist;
oprand2 = oplist;
num1 = numlist;
while (oprand2)
{
num2 = num1->next;
if (oprand2->op == 2)
{
num1->val = calc(num1->val, oprand2->op, num2->val);
num1->next = num2->next;
free(num2);
num2 = num1->next;
if (oprand2 == oplist)
{
oplist = oprand2->next;
free(oprand1);
oprand1 = oplist;
oprand2 = oplist;
}
else
{
oprand1->next = oprand2->next;
free(oprand2);
oprand2 = oprand1->next;
}
}
else
{
if (oprand1 != oprand2) oprand1 = oprand2;
oprand2 = oprand2->next;
num1 = num2;
num2 = num2->next;
}
}
oprand = oplist;
num = numlist;
res = num->val;
num = num->next;
while (oprand)
{
res = calc(res, oprand->op, num->val);
oprand = oprand->next;
num = num->next;
}
while (oplist)
{
oprand = oplist->next;
free(oplist);
oplist = oprand;
}
while (numlist)
{
num = numlist->next;
free(numlist);
numlist = num;
}
if (res == (long)Result) write_express(op, res);
}
fclose(fp);
return 1;
}
long int calc(long int num1, int op, long int num2)
{
long int res;
switch (op)
{
case 0:
res = num1 + num2;
break;
case 1:
res = num1 - num2;
break;
case 2:
res = num1 * 10 + num2;
break;
}
return(res);
}
void write_express(int *op, long int res)
{
int i;
for (i = 0; i < 8; i++)
{
fprintf(fp, "%d", i+1);
switch (op[i])
{
case 0: fprintf(fp, "+"); break;
case 1: fprintf(fp, "-"); break;
case 2: break;
}
}
fprintf(fp, "9=%ld/n", res);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
计算结果如下:
1+2+3-4+5+6+78+9=100
1+2+34-5+67-8+9=100
1+23-4+5+6+78-9=100
1+23-4+56+7+8+9=100
12+3+4+5-6-7+89=100
12+3-4+5+67+8+9=100
12-3-4+5-6+7+89=100
123+4-5+67-89=100
123+45-67+8-9=100
123-4-5-6-7+8-9=100
123-45-67+89=100
- 上升数列的生成算法
- 不重复随机数列的生成算法
- 最长上升子数列
- 最长上升子数列
- 不重复随机数列生成算法
- 不重复随机数列生成算法
- 不重复随机数列生成算法
- 不重复随机数列生成算法
- 不重复随机数列生成算法
- 不重复随机数列生成算法
- 不重复随机数列生成算法
- 基于梯度上升算法的Logistic回归
- java对角线数列的算法
- fibonacci数列的矩阵算法
- 利用数列对应的生成函数求解数列的通项式
- 一些常见数列的生成函数推导
- python中生成斐波拉契数列的方法
- Educational Codeforces Round 15--AMaximum Increase--求最长上升数列的长度
- ASD Practices敏捷开发实践
- php技术资料02
- 在Struts2中使用SiteMesh插件
- WebLogic 9中console异地IP登录不上的解决方法
- 笔试解答-----大家检查一下了
- 上升数列的生成算法
- 三线合一:三金叉见底
- 10项调试基本规则
- 开源网络蜘蛛(Spider)一览
- 关于在ASP.NET中以DCOM方式操作Excel的几个问题
- VB.net 2005 的应用程序的用户参数设置
- 数据库设计规范
- MySQL 5.0安装的图解
- 那里有鱼