题目大意:

题目给出一个由“*”构成的乘法式子。已知一个范围为[0,9]的整数集合,用集合中的数字替换“*”可能使式子成立,要求编程求出使式子成立的方案的数量。

思路:

用深搜遍历所有可能方案即可,具体思路见代码。

代码:

/*
ID: lujunda1
LANG: C++
PROG: crypt1
*/
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdio>
#include<stdlib.h>
using namespace std;
//num[]用于存储两个乘数,例如123*45,那么num[]={1,2,3,4,5}。 
int num[5];
//mark[]用于判断某数字是否属于所给集合。 
bool mark[10];
//输入 
void input()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<10;i++)
		mark[i]=false;
	for(int i=0,temp;i<n;i++)
	{
		scanf("%d",&temp);
		mark[temp]=true;
	}
}
//判断整数n的各位数字是否都属于集合 
int check_num(int n)
{
	//length用于记录整数n的长度。 
	int length=0;
	for(;n;n/=10,length++)
		//若某位数字不属于集合,则返回-1。 
		if(!mark[n%10])
			return -1;
	//若整数n的各位数字都属于集合,则返回其长度。
	//返回长度是因为题目所给乘法式子对不同位置的整数有格式(长度)限制,要判断整数n是否符合格式。 
	return length;
}
//判断当前num[]所表示的乘数组合是否符合乘法式子与格式的要求。 
bool check()
{
	//a是被乘数,b是乘数,d是乘数的个位,c是乘数的十位。 
	int a=num[0]*100+num[1]*10+num[2],b=num[3]*10+num[4],c=num[4],d=num[3];
	//a*c和a*d分别是乘法式子第4行和第3行上的整数。它们的长度为3。 
	//a*b是结果,长度应该为4。 
	if(check_num(a*c)==3&&check_num(a*d)==3&&check_num(a*b)==4)
		return true;
	return false;
}
//利用深搜,遍历所有可能的乘数组合。
//order表示num[]中的第order位,从0开始。 
int dfs(int order)
{
	if(order==5)
		return check()?1:0;
	int sum=0;
	for(int i=0;i<10;i++)
		if(mark[i])
		{
			//不能有前导0 
			if((order==0||order==3)&&i==0)
				continue;
			num[order]=i;
			sum+=dfs(order+1);
		}
	return sum;
}
int main()
{
	freopen("crypt1.in","r",stdin);
	freopen("crypt1.out","w",stdout);
	input();
	printf("%d\n",dfs(0));
}