您的位置:首页 > 其它

【USACO-Chapter1-1.3】【模拟】Prime Cryptarithm

2012-08-04 20:18 387 查看
【题目描述】

下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式。

* * *
x     * *
----------
* * *
* * *
----------
* * * *

数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0。

注意一下在美国的学校中教的“部分乘积”,第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积.

写一个程序找出所有的牛式。

【输入格式】(crypt1.in)

Line 1:数字的个数n。

Line 2:N个用空格分开的数字(每个数字都属于{1,2,3,4,5,6,7,8,9})。

【输出格式】(calffac.out)

共一行,一个数字。表示牛式的总数。


【输入样例】

5
2 3 4 6 8

【输出样例】

1
【样例分析】
2 2 2
x     2 2
----------
4 4 4
4 4 4
----------
4 8 8 4
注意:结果只能为4位

按照题目要求搜就是了,这道题也可以直接枚举所有可能,但我从觉得那样做不好,所以写了个dfs+判断,可能是最长的代码了吧。。。

代码:

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10 + 10;
int m[maxn];
int a[maxn],b[maxn];//1,2,3代表个位,十位,百位(下同)。a是第一行,b是第二行
int t[maxn];//最后结果
int com1[maxn],com2[maxn];//分别表示中间两行
bool sign[maxn];
int n;
int ans = 0;

void init()
{
freopen("crypt1.in","r",stdin);
freopen("crypt1.out","w",stdout);
}

void readdata()
{
memset(sign,false,sizeof(sign));
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
scanf("%d",&m[i]);
sign[m[i]] = true;
}
}

bool check()
{
memset(t,0,sizeof(t));
memset(com1,0,sizeof(com1));
memset(com2,0,sizeof(com2));
for(int i = 1;i <= 2;i++)
for(int j = 1;j <= 3;j++)
{
if(i == 1)
{
com1[j] += b[i] * a[j];
while(com1[j] >= 10)
{
com1[j] -= 10;
++com1[j+1];
}
if(j == 1)
{
t[1] = com1[j];
if(!sign[t[1]])return false;
}
if(!sign[com1[j]])return false;
if(com1[4] != 0)return false;
}
if(i == 2)
{
com2[j] += b[i] * a[j];
while(com2[j] >= 10)
{
com2[j] -= 10;
++com2[j+1];
}
if(!sign[com2[j]])return false;
if(com2[4] != 0)return false;
}
}
int i = 2;
while(i <= 3)
{
t[i] += com1[i] + com2[i-1];
while(t[i] >= 10)
{
t[i] -= 10;
++t[i+1];
}
if(!sign[t[i]])return false;
++i;
}
t[4] += com2[3];
if(t[4] > 10)
{
return false;
}
else
{
if(sign[t[4]])
{
return true;
}
else
{
return false;
}
}
return true;
}

void dfs2(int x)
{
if(x == 3)
{
if(check())
{
++ans;
}
return;
}
for(int i = 1;i <= n;i++)
{
b[x] = m[i];
dfs2(x+1);
b[x] = 0;
}
}

void dfs1(int x)
{
if(x == 4)
{
dfs2(1);
return;
}
for(int i = 1;i <= n;i++)
{
a[x] = m[i];
dfs1(x+1);
a[x] = 0;
}
}

void solve()
{
dfs1(1);
printf("%d\n",ans);
}

int main()
{
init();
readdata();
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: