算式迷题 求解

pcbit 2005-04-28 08:32:17
下列竖式中每个不同字母代表不同数字:
s e n d
+ m o r e
---------------
m o n e y
编写程序,破译每个字母代表的数字



求算法,谢谢
...全文
150 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
mmmcd 2005-04-28
  • 打赏
  • 举报
回复
/*问题:等式 SEND + MORE = MONEY 中,每个大写字母表示一个数字。求出这些数字,使等式成立。
算法分析:既然字母数不太多,只有8种,使用穷举,10个数中取8个进行全排列,共1814400种情况,
计算约耗时19秒。
*/
#include<iostream>
#include<string>
#include<vector>
#include<iomanip>
#include<conio.h>
#include<ctype.h>
using namespace std;

string a[10]; //记录要处理算式中的字符串
int n;
vector<char> c; //将要处理的字母列表
int cc[26],c_n[26]; //cc[i]记录ASCII值为i+96的字符对应的数字,c_n[i]记录ASCII值为i+96的字符
bool c1[26],mark[10];//c1[i]标记ASCII值为i+96的字符是否为首字母,mark[i]记录数字i是否出现过

bool in(char ch)//判断某字母ch是否出现过,是则返回false,否则true.
{
for(int i=0;i<c.size();i++)
{
if(c[i]==ch)
return false;
}
c.push_back(ch);
return true;
}

void reading()//封装数据输入过程,可扩充其功能,例如等式中的字符串或计算式可自由输入(本程序未实现)
{
int i;
c.clear();
n=3;
a[0]="SEND";
a[1]="MORE";
a[2]="MONEY";
int k=0;
for(i=0;i<n;i++)
{
if(i==n-2){
cout<<'+'<<setw(5)<<a[i]<<endl;
cout<<"--------\n";
}
else
cout<<setw(6)<<a[i]<<endl;
for(int j=0;j<a[i].size();j++)
{
if(in(a[i][j])) //判断某字母是否出现过
c_n[a[i][j]-'A']=k++; //若没出现则给字母标号,例如c_n['M'-'A']=0表示M为第一个字母
c1[c_n[a[i][j]-'A']]=false;
}
c1[c_n[a[i][0]-'A']]=true; //记录首字母,因它不能为零
}
cout<<endl;
for(i=0;i<10;i++)
{
mark[i]=false;
}
}

int value(string s) //传递字符串,求其值(正整数)
{
int r=0;
for(int i=0;i<s.size();i++)
{
r=r*10+cc[c_n[s[i]-'A']];
}
return r;
}

bool check() //判断等式成立否,成立true,否则false
{
int r=0;
for(int i=0;i<n-1;i++)
{
r+=value(a[i]); //字母赋值后,计算字串的值
}
int r1=value(a[i]);
return r==r1;
}

void output() //输出结果
{
string rc;
for(int i=0;i<n;i++)
{
if(i==n-2){
cout<<'+'<<setw(5)<<value(a[i])<<endl;
cout<<"--------\n";
}
else
cout<<setw(6)<<value(a[i])<<endl;
}
cout<<endl;
}

void trace(int k) //对第k个字母处理,使用经典的回溯结构
{
if(k==c.size()) //当字母都赋值完
{
if(check()) //判断等式成立否
output(); //成立则输出结果
}
else
{
for(int i=0;i<10;i++)
{
if(i==0&&c1[k])continue;//防止首字母为零,本题中,S与M不能为零
if(mark[i])
continue;
mark[i]=true; //作标记,数字i已用过(保证唯一性)
cc[k]=i; //给第k个字母赋值i
trace(k+1); //对第k+1个字母处理
mark[i]=false;//请除标记
}
}
}

void doing()
{
trace(0); //对第一个字母处理
}

int main() //主过程
{
reading();//数据输入
doing(); //问题求解并输出结果
cout<<"Press any key to continue.\n";
getch();
return 0;
}
/*
运行结果

SEND
+ MORE
--------
MONEY

9567
+ 1085
--------
10652
*/

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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