算是比较水的题。
问题分为两部分,一部分是计算罗马数字表达式是否正确,这个基本上没有难度,只是题目描述的规则十分难理解,我只好GOOGLE了一下罗马数字的使用规则,其实对这道题来说很简单,直接从后往前遍历,只要前面的数字比后面大就直接判为负数,因为输入中不会包含不合法的罗马数字。
第二问实际上就是将0到9映射到7个符号,再判断由这七个符号组成的算式是错误、有一种情况满足还是有多种情况满足,一共有A10 7=604800种映射方式。直接暴力即可。
如果数据量比较大的话,有一种剪枝方式就是先把两个加数中包含的符号的映射确定下来,再逐位判断加和是否满足要求。。。不过对这题没有必要。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char a[10],b[10],c[10],make[30];
int la,lb,lc,l,map[100],value[100],front[100],vis[10],ok;
int judge()
{
int aa=0,bb=0,cc=0,i,j;
for(i=0;i<la;i++)
{
aa=10*aa+(value[a[i]]);
}
for(i=0;i<lb;i++)
{
bb=10*bb+(value[b[i]]);
}
for(i=0;i<lc;i++)
{
cc=10*cc+(value[c[i]]);
}
if(aa+bb==cc)
return 1;
else
return 0;
}
void solve(char p[10],int index,int l)
{
int i,j;
if(ok==2)
return ;
if(index==l)
{
if(judge())
ok++;
return ;
}
if(value[p[index]]!=-1)
solve(p,index+1,l);
else
{
if(front[p[index]]!=1&&vis[0]==0)
{
vis[0]=1;
value[p[index]]=0;
solve(p,index+1,l);
if(ok==2)
return ;
vis[0]=0;
value[p[index]]=-1;
}
for(i=1;i<=9;i++)
{
if(vis[i]==0)
{
vis[i]=1;
value[p[index]]=i;
solve(p,index+1,l);
if(ok==2)
return ;
vis[i]=0;
value[p[index]]=-1;
}
}
}
}
int main ()
{
map['I']=1,map['V']=5,map['X']=10,map['L']=50,map['C']=100,map['D']=500,map['M']=1000;
char input[30];
int i,j;
int va,vb,vc;
while(gets(input)&&input[0]!='#')
{
memset(a,0,10);
memset(b,0,10);
memset(c,0,10);
memset(value,-1,400);
memset(front,0,400);
memset(vis,0,40);
va=vb=vc=ok=l=0;
for(i=0,la=0;input[i]!='+';i++)
{
a[la++]=input[i];
make[l++]=input[i];
}
front[a[0]]=1;
for(i++,lb=0;input[i]!='=';i++)
{
b[lb++]=input[i];
make[l++]=input[i];
}
front[b[0]]=1;
for(i++,lc=0;input[i]!=0;i++)
{
c[lc++]=input[i];
make[l++]=input[i];
}
front[c[0]]=1;
//puts(a);puts(b);puts(c);
for(i=la-1;i>=0;)
{
va+=map[a[i--]];
if(i>=0&&map[a[i]]<map[a[i+1]])
va-=map[a[i--]];
}
for(i=lb-1;i>=0;)
{
vb+=map[b[i--]];
if(i>=0&&map[b[i]]<map[b[i+1]])
vb-=map[b[i--]];
}
for(i=lc-1;i>=0;)
{
vc+=map[c[i--]];
if(i>=0&&map[c[i]]<map[c[i+1]])
vc-=map[c[i--]];
}
if(va+vb==vc)
printf("Correct ");
else
printf("Incorrect ");
solve(make,0,l);
if(ok==0)
printf("impossible\n");
else if(ok==1)
printf("valid\n");
else
printf("ambiguous\n");
}
return 0;
}