UVA 185 - Roman Numerals

题目大意:给出一个字符串的等式,问这个字符串是罗马等式吗? 有符合的阿拉伯等式吗?前者是就输出correct or incorrect ,后者就得分情况:impossible 没有符合阿拉伯等式的字母组合,valid 能组成阿拉伯等式的字母组合等于1,ambiguous 能组成阿拉伯等式的字母组合大于等于2,

解题思路:1、能不能组成罗马等式的规则:每个当前的字母(i)的左边的字母(i-1)所对应的值如果比i所对应的值小的话,字母(i-1)的值就取负值,否则就取正值。最后判断是否等是式左右成立。


2、能不能组成阿拉伯等式的话,就是每个字母都可以用 0 - 9 之间的数字去替代,看是否有是左右两边等式成立的。

注意:0单独出现,和出现前导0的情况,都是不要的,需要排除。然后相同的字母表示一样的值。这里就将每个字母的情况都枚举出来,然后去掉0出现错误的情况,dfs()找出符合的组合。

#include <cstdio>
#include <cstring>

int yes, len, count, change[200], vis[10] = {0};
char str[100], letter[8] = {"IVXLCDM"}, record[8];

bool judge() {
	int rec[200] = {0}, num[3] = {0}, cnt = 0;

	for (int i = 0; i < len; i++)
		if (str[i] != '+' && str[i] != '=') {
			num[cnt] += (change[str[i]] >= change[str[i + 1]] ? change[str[i]] : -change[str[i]]);
			if (rec[str[i]]++ ==  0)
				record[count++] = str[i];
		}
		else 
			cnt++;

	return num[0] + num[1] == num[2];
}

int DFS(int cur) {
	if (cur == count) {
		int num[3] = {0}, cnt = 0;
		for (int i = 0; i < len; i++)
			str[i] != '+' && str[i] != '=' ? num[cnt] = num[cnt] * 10 + change[str[i]] : cnt++;

		if (num[0] + num[1] == num[2])
			yes++;
	}
	else for (int i = 0; i < 10; i++) {
		change[record[cur]] = i;
		if (vis[i] || change[str[0]] == 0)
			continue;
		vis[i] = 1;
		DFS(cur + 1);
		vis[i] = 0;
	}

	return yes;
}

int main() {
	while (scanf("%s", str), str[0] != '#') {
		yes = count = 0;
		len = strlen(str);	
		change['I'] = 1;
		for (int i = 1; i < 7; i ++)
			change[letter[i]] = change[letter[i-1]] * (i % 2 ? 5 : 2);

		printf(judge() ? "Correct " : "Incorrect ");
		printf(DFS(0) ? yes > 1 ? "ambiguous\n" : "valid\n" : "impossible\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰阔落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值