uva 185

题意:两个问题,一是:问你是否满足罗马数字的等式,二是:是否有阿拉伯数字满足等式,第一个问题的注意点是:如果后一个的字符所代表的数字比它大,那么这个字符将是减去的,而不是加,第二个问题:我是把所有出现的字符都记录下来,然后就是一个个的搜索,注意的是:第一个不能是零

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 30;

char str[MAXN];
char str_path[MAXN][MAXN];
char kind_str[MAXN];
int path_num,val[100];
int path_val[MAXN],sign,kind;
int vis[10];
int hash[100];
int Vkind[100];

void init()
{
    int len = strlen(str);
    int cnt = 0;
    str[len] = '+';
    int t = 0;
    path_num = 0;
    kind = 0;
    for (int i = 0; i <= len; i++)
    {
        if (str[i] != '+' && str[i] != '=')
        {
            str_path[path_num][cnt++] = str[i];
            path_val[path_num] += val[str[i]];
            if (!hash[str[i]])   // 储存所有出现的字符
            {
                kind_str[kind] = str[i];
                kind++;
                hash[str[i]] = 1;
            }
            if (val[str[i]] > t)
                path_val[path_num] -= 2 * t;
            t = val[str[i]];
        }
        else 
        {
            str_path[path_num][cnt] = '\0';
            t = 0;
            path_num++;
            cnt = 0;
        }
    }
}

int judge()
{
    int sum=0;
    for (int i = 0; i < path_num-1; i++)
        sum += path_val[i];
    if (sum == path_val[path_num-1])
        return 1;
    else return 0;
    
}

void dfs(int cur)
{
    if (sign == 2)
        return;
    
    if (cur >= kind)
    {
        int Vnum[path_num];
        memset(Vnum,0,sizeof(Vnum));
        for (int i = 0; i < path_num; i++)
            for(int j = 0; j < strlen(str_path[i]); j++)
                Vnum[i] = Vnum[i] * 10 + Vkind[str_path[i][j]];   
        int sum = 0;
        for (int i = 0; i < path_num - 1; i++)
            sum += Vnum[i];
        if (sum == Vnum[path_num-1])
            sign++;
        return ;
    }
    
    for (int i = 0; i <= 9; i++)
    {
        if (cur == 0 && i == 0)
            continue;

       if (!vis[i]) 
       {
            vis[i] = 1;
            Vkind[kind_str[cur]] = i;    // 储存字符所表示的数字
            dfs(cur+1);
            vis[i] = 0;
       }
    }
}

int main()
{
    val['I']=1,val['V']=5,val['X']=10,val['L']=50,val['C']=100;
    val['D']=500,val['M']=1000;
    while (scanf("%s",str) != EOF && str[0] != '#')
    {
        memset(vis,0,sizeof(vis));
        memset(hash,0,sizeof(hash));
        memset(path_val,0,sizeof(path_val));
        init();

        int flag = judge();
        if (flag)
            printf("Correct ");
        else printf("Incorrect ");

        sign = 0;
        dfs(0);
        if (sign == 0)
            printf("impossible\n");
        else if (sign == 1)
            printf("valid\n");
        else printf("ambiguous\n");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值