暴力美学----枚举的魅力

直接上示例,不多bb,自己体会。

【例1】
[ ] [ ] [ ]+[ ] [ ] [ ]=[ ] [ ] [ ],将数字1~9分别填入其中,每个数字只能使用一次并使得等式成立。请问一共有多少种合理的组合?

//用a[1]~a[9]表示填入的九个数,用一个book数组来标记已经出现的数字
#include<stdio.h>
int main()
{
	int a[10],i,total=0,book[10],sum;
	for(a[1]=1;a[1]<=9;a[1]++)
	for(a[2]=1;a[2]<=9;a[2]++)
	for(a[3]=1;a[3]<=9;a[3]++)
	for(a[4]=1;a[4]<=9;a[4]++)
	for(a[5]=1;a[5]<=9;a[5]++)
	for(a[6]=1;a[6]<=9;a[6]++)
	for(a[7]=1;a[7]<=9;a[7]++)
	for(a[8]=1;a[8]<=9;a[8]++)
	for(a[9]=1;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);
	getchar();getchar();
	return 0;
}

【例2】
在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
int main()
{
	char a[20][21];//假设这里的地图大小不超过20*20
	int i,j,sum,map=0,p,q,x,y,n,m;
	//读入n和m,n表示有多少行字符,m表示每行有多少列
	scanf("%d %d",&n,&m);

	//读入n行字符
	for(i=0;i<=n-1;i++)
		scanf("%s",a[i]);

	//用两重循环枚举地图中的每个点
	for(i=0;i<=n-1;i++)
	{
		for(j=0;j<=m-1;j++)
		{
			//首先判断这个点是不是平地,是平地才能放炸弹
			if(a[i][j]=='.')
			{
				sum=0;//sum用来计数(可以消灭的敌人数),初始化为0
				//将当前坐标i,j复制到两个新变量x,y中,以便向上下左右四个方向分别统计
				//可以消灭的敌人数
				//向上统计可以消灭的敌人数
				x=i; y=j;
				while(a[x][y]!='#')//判断是不是墙,不是墙就可以继续
				{
					//如果当前点是敌人,则进行计数
					if(a[x][y]=='G')
						sum++;
					//x--的作用是继续向上统计
					x--;
				}

				//向下统计可以消灭的敌人数
				x=i; y=j;
				while(a[x][y]!='#')
				{
					if(a[x][y]=='G')
						sum++;
					//x++的作用是继续向下统计
					x++;
				}

				 //向左统计可以消灭的敌人数
				x=i; y=j;
				while(a[x][y]!='#')
				{
					if(a[x][y]=='G')
						sum++;
					//y--的作用是继续向左统计
					y--;
				}

				//向右统计可以消灭的敌人数
				x=i; y=j;
				while(a[x][y]!='#')
				{
					if(a[x][y]=='G')
						sum++;
					//y++的作用是继续向右统计
					y++;
				}

				//更新map的值
				if(sum>map)
				{
					//如果当前点所能消灭的敌人总数大于map,这更新map
					map=sum;
					//并用p和q记录当前点的坐标
					p=i;
					q=j;
				}
			}
		}
	}

	printf("将炸弹放在(%d,%d),最多可以消灭%d个敌人",p,q,map);
	getchar();getchar();
	return 0;
}

【例3】
有n根火柴,希望拼出A+B=C的等式。等式中的A,B,C,均是用火柴拼出来的整数(若该数非零,则最高位不能是0),数字0~9的拼法如下:
在这里插入图片描述
注意:
1.加号与等号各自需要两个火柴;
2.如果A不等于B,则A+B=C与B+A=C视为不同的等式;
3.所有火柴均要用上;
4.火柴数量不超过24;
5.限时1秒。

tips:
题目最多有24根火柴,出去“+”和“=”占用的4根火柴,最多还剩下20根火柴,而在0~9这十个数中,数字1用到的火柴数最少,只需要2根火柴。而20根火柴最多能组成10个1。因此A+B=C这个等式中A、B、C中任意一个数字都不能超过1111。

#include<stdio.h>
int fun(int x)
{
	int num=0;//用来计数的变量,要初始化
	int f[10]={6,2,5,5,4,5,6,3,7,6};
	//用一个数组来记录0~9每个数字需要用到多少根火柴
	while(x/10!=0)
	{
		//获得x的末尾数字并将此数用到的火柴数累加到sum中
		num +=f[x%10];
		x=x/10;//去掉x的末尾数字
	}
	//最后加上此时x所需用到的火柴数(此时x一定是一个个位数)
	num +=f[x];
	return num;//返回需要用到的火柴总数
}

int main()
{
	int a,b,c,m,sum=0;//sum是用来计数的,要初始化
	scanf("%d",&m);//读入火柴的个数

	//开始枚举a和b
	for(a=0;a<=1111;a++)
	{
		for(b=0;b<=1111;b++)
		{
			c=a+b;//计算出c
			//fun是我们自己写的子函数,用来计算一个数所需要用到的火柴数
			//当a使用的火柴总数+b使用的火柴总数+c使用的火柴总数之和恰好
			//等于m-4的时候,则成功找到一组解
			if(fun(a)+fun(b)+fun(c)==m-4)
			{
				printf("%d+%d=%d\n",a,b,c);
    			sum++;
			}
		}
	}
	printf("一共可以拼出%d个不同的等式",sum);
	getchar();;getchar();
	return 0;
}
发布了20 篇原创文章 · 获赞 20 · 访问量 464

猜你喜欢

转载自blog.csdn.net/weixin_44305051/article/details/104213718