三个三位数相加的枚举法问题

liu6tot 2016-03-08 08:15:33
问题描述:
设计描述:
1.定义数组存储9个参与运算的变量,并设置一个9层循环;
2.为了保证9个数不重复,设置一个book数组用来标记某数(0~9)的数字是否重复过,出现设为1,统计book中1的个数,如果为9说明出现的数字不重复。
3.每个数的百位不能为0。
具体算法:

#include<stdio.h>
int main()
{
int a[10],i,total=0,book[10],sum;
//这里用a[1]-a[9]代表上一算法中的a~j
for (a[1]=1;a[1]<=9;a[1]++)
for (a[2]=0;a[2]<=9;a[2]++)
for (a[3]=0;a[3]<=9;a[3]++)
for (a[4]=1;a[4]<=9;a[4]++)
for (a[5]=0;a[5]<=9;a[5]++)
for (a[6]=0;a[6]<=9;a[6]++)
for (a[7]=1;a[7]<=9;a[7]++)
for (a[8]=0;a[8]<=9;a[8]++)
for (a[9]=0;a[9]<=9;a[9]++)
{
for(i=1;i<=9;i++)//初始化book数组
book[i]=0;
for(i=1;i<=9;i++)
book[a[i]]=1;
//统计出现多少个不同的数
sum=0;
for(i=1;i<=9;i++)
sum+=book[i];
//如果出现9个不同的数,并且满足等式条件,则输出
if(sum==9 && a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]
==a[7]*100+a[8]*10+a[9])
{
total++;
printf("%d%d%d+%d%d%d=%d%d%d\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
}
}
printf("total=%d",total/2);//除2抛出重复的情况统计
getchar();getchar();
return 0;
}

现在所遇到的问题:
貌似这个算法对并不能正常工作,主要问题是当每个数的十位、个位出现0时,book数组的标记和我预想的会有不同,所以最后统计出来的可能的加法组合会有大量重复,一时间我也不知道该怎样修改,还请C/C++版的个位大神不吝赐教。

9层循环,算法的运算速度也是醉了,不知能有什么好的修改方案?
...全文
396 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
galiniur0u 2016-03-16
  • 打赏
  • 举报
回复
引用 8 楼 liu6tot 的回复:
究竟该怎样统计满足条件的等式数目呢?
if((a[0] * 100 + a[1] * 10 + a[2] + a[3] * 100 + a[4] * 10 + a[5]) == (a[6] * 100 + a[7] * 10 + a[8]) && a[0] != 0 && a[3] != 0 && (a[0] * 100 + a[1] * 10 + a[2] <= 500))
{
count ++;
}
设置全局的count,在这个判断里,如果进入这个判断就将count++;
liu6tot 2016-03-15
  • 打赏
  • 举报
回复
究竟该怎样统计满足条件的等式数目呢?
赵4老师 2016-03-09
  • 打赏
  • 举报
回复
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门! 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出
liu6tot 2016-03-09
  • 打赏
  • 举报
回复
引用 5 楼 galiniur0u 的回复:
思路: 1、楼主可以算10个数的全排列,这样可以去掉重复的数字的判断。 2、计算前9个数字,前三个数字+中间三个数字==后三个数字。 3、打印输出a[0] * 100 +a[1] * 10 + a[2] <= 500的情况。
#include <stdlib.h>
#include <stdio.h>

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

int all(int m, int a[], int num)
{
	int i = 0;
	if(m == 10)
	{
		if((a[0] * 100 + a[1] * 10 + a[2] + a[3] * 100 + a[4] * 10 + a[5]) == (a[6] * 100 + a[7] * 10 + a[8]) && a[0] != 0 && a[3] != 0 && (a[0] * 100 + a[1] * 10 + a[2] <= 500))
		{
			printf("%8d : ", num);
			for(i = 0; i < 3; i ++)
			{
				printf("%d ", a[i]);
			}
			printf("+ ");
			for(i = 3; i < 6; i ++)
			{
				printf("%d ", a[i]);
			}
			printf("= ");
			for(i = 6; i < 9; i ++)
			{
				printf("%d ", a[i]);
			}
			printf("\n");
		}
		return ++ num;
	}
	for(i = m; i < 10; i ++)
	{
		swap(&a[i], &a[m]);
		num = all(m + 1, a, num);
		swap(&a[i], &a[m]);
	}
	return num;
}

int main()
{
	int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	all(0, a, 0);
}
请问兄台 在递归条件下怎么统计满足条件的等式数目呢?
paschen 2016-03-08
  • 打赏
  • 举报
回复
这样或许会好一点: 先把所有不重复的三位数找出来,放到一个数组里 然后遍历这个数组,使里面任意两个数相加一次,判断是否满足
sdghchj 2016-03-08
  • 打赏
  • 举报
回复
void fun(int *p,int c,short& wFlag,unsigned int& nCount)
{
	for (int i = 0; i < 10; ++ i)
	{
		short f = 1 << i;
		if ((wFlag & f) == 0)
		{
			p[c] = i;
			if (c == 8)
			{
				if (p[0]*100 + p[1]*10 + p[2] + p[3]*100 + p[4]*10 + p[5] == p[6]*100 + p[7]*10 + p[8])
				{
					++ nCount;
					printf("%d,%d,%d,%d,%d,%d,%d,%d,%d\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8]);
				}
				return;
			}
			else
			{
				wFlag |= f;
				fun(p,c+1,wFlag,nCount);
				wFlag &= (~f);
			}
		}
	}
}

int main()
{
	int p[9];
	short wFalg = 0;
	unsigned int nCount = 0;
	for (int i = 0; i < 10; ++ i)
	{
		p[0] = i;
		wFalg = 1;
		fun(p,1,wFalg,nCount);
	}
	return 0;
}
「已注销」 2016-03-08
  • 打赏
  • 举报
回复
等号左边,最小的组合是(我目前能想到的): 205+134 105+234 等号右边,最大的组合是: 987 没必要全部列举 或者搞一个排列组合
fefe82 2016-03-08
  • 打赏
  • 举报
回复
为什么你的循环都是 1 到 9 ,而不是 0 到 9 ...
galiniur0u 2016-03-08
  • 打赏
  • 举报
回复
思路: 1、楼主可以算10个数的全排列,这样可以去掉重复的数字的判断。 2、计算前9个数字,前三个数字+中间三个数字==后三个数字。 3、打印输出a[0] * 100 +a[1] * 10 + a[2] <= 500的情况。
#include <stdlib.h>
#include <stdio.h>

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

int all(int m, int a[], int num)
{
	int i = 0;
	if(m == 10)
	{
		if((a[0] * 100 + a[1] * 10 + a[2] + a[3] * 100 + a[4] * 10 + a[5]) == (a[6] * 100 + a[7] * 10 + a[8]) && a[0] != 0 && a[3] != 0 && (a[0] * 100 + a[1] * 10 + a[2] <= 500))
		{
			printf("%8d : ", num);
			for(i = 0; i < 3; i ++)
			{
				printf("%d ", a[i]);
			}
			printf("+ ");
			for(i = 3; i < 6; i ++)
			{
				printf("%d ", a[i]);
			}
			printf("= ");
			for(i = 6; i < 9; i ++)
			{
				printf("%d ", a[i]);
			}
			printf("\n");
		}
		return ++ num;
	}
	for(i = m; i < 10; i ++)
	{
		swap(&a[i], &a[m]);
		num = all(m + 1, a, num);
		swap(&a[i], &a[m]);
	}
	return num;
}

int main()
{
	int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	all(0, a, 0);
}

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧