题意:
给定一个字母组成的等式,判断其在罗马形式下是否成立,和判断其在阿拉伯形式下有多少种可能解。
思路:
对于第一种判断,直接利用题目规则将字母转成数字后就可以判断;第二种阿拉伯形式下,我们可以通过枚举每个字母的值然后进行判断,注意第一个字母不能为0,然后不同位置上相同字母的值是相同的.
代码如下:
<span style="font-size:18px;">#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int d[100],cnt;
int vis[100],a[5],L[10];
char str[5][100];
int check(char *str,int x)
{
int len=strlen(str),i,j;
if(x+1>=len||x+2>=len)
return 0;
if(d[str[x]-'A']>d[str[x+1]-'A']&&d[str[x+1]-'A']<d[str[x+2]-'A'])
return 1;
return 0;
}
int getsum(char *str)
{
int i,j,k,len=strlen(str);
int sum=0;
for(i=0;i<len;i++)
{
if(check(str,i))
{
sum+=d[str[i]-'A']-d[str[i+1]-'A'];
i++;
}
else
sum+=d[str[i]-'A'];
}
return sum;
}
void dfs(int flag,int cur,int sum,int len)
{
//剪枝
if(cnt>=2)
return ;
int i,j,k;
if(cur==len)
{
if(flag==3)
{
if(a[1]+a[2]==sum)
cnt++;
return ;
}
else
{
a[flag]=sum;
dfs(flag+1,0,0,L[flag+1]);
}
}
else if(cur!=0&&vis[str[flag][cur]-'A']!=-1)
dfs(flag,cur+1,sum*10+vis[str[flag][cur]-'A'],len);
else if(cur==0&&vis[str[flag][cur]-'A']>0)
dfs(flag,cur+1,sum*10+vis[str[flag][cur]-'A'],len);
else
for(i=0;i<=9;i++)
{
if(cur==0&&vis[str[flag][cur]-'A']<=0&&i==0)
continue;
vis[str[flag][cur]-'A']=i;
dfs(flag,cur+1,sum*10+i,len);
vis[str[flag][cur]-'A']=-1;
}
}
int main()
{
d['I'-'A']=1; d['V'-'A']=5; d['X'-'A']=10;
d['L'-'A']=50; d['C'-'A']=100;
d['D'-'A']=500; d['M'-'A']=1000;
int i,j,k;
char ch[100];
while(gets(ch))
{
if(ch[0]=='#')
break;
k=0;
int len=strlen(ch);
for(i=0;i<len;i++)
{
if(ch[i]=='+')
break;
str[1][k++]=ch[i];
}
L[1]=i;
str[1][k]='\0';
k=0;
for(j=i+1;j<len;j++)
{
if(ch[j]=='=')
break;
str[2][k++]=ch[j];
}
L[2]=j-i-1;
str[2][k]='\0';
k=0;i=j;
for(j=i+1;j<len;j++)
str[3][k++]=ch[j];
L[3]=len-i-1;
str[3][k]='\0';
int sum1=getsum(str[1]);
int sum2=getsum(str[2]);
int sum3=getsum(str[3]);
if(sum1+sum2==sum3)
printf("Correct ");
else
printf("Incorrect ");
cnt=0;
memset(vis,-1,sizeof(vis));
dfs(1,0,0,L[1]);
if(cnt==0)
printf("impossible\n");
if(cnt==1)
printf("valid\n");
if(cnt>1)
printf("ambiguous\n");
}
return 0;
}
</span>