您的位置:首页 > 其它

UVa 185 - Roman Numerals

2016-04-06 22:37 711 查看
題目:給你一個羅馬數組組成的計算式A+B=C,判斷等式是否成立,有兩種方案:

           1.羅馬數字:每個字母代表一個數字,相鄰數字左邊的小就右邊減去左邊的數字,否則加和;

           2.阿拉伯數字:每個字母用不同的數字代替(無前導零)。

分析:圖論,搜索。數據較小,利用回溯法搜索即可,可以按數字搜索,也可以按字母搜索。

說明:用char存儲數據溢出,好久才發現,╮(╯▽╰)╭。

#include <cstring>
#include <cstdio>

char str[33], buf[3][11], maps[9];
int roman[128], first[128], visit[128], used[10], digit[128];

int ans;
int value[3];
void dfs(int d, int n)
{
if (ans > 1) return;
if (d >= n) {
for (int i = 0; i < 3; ++ i) {
value[i] = 0;
for (int j = 0; buf[i][j]; ++ j)
value[i] = value[i]*10 + digit[buf[i][j]];
}
ans += (value[0]+value[1] == value[2]);
return;
}else {
for (int i = 0; i <= 9; ++ i) {
if (used[i] || !i && first[maps[d]]) continue;
digit[maps[d]] = i;
used[i] = 1;
dfs(d+1, n);
used[i] = 0;
if (ans > 1) return;
}
}
}

int main()
{
roman['I'] = 1; roman['V'] = 5;
roman['X'] = 10; roman['L'] = 50;
roman['C'] = 100; roman['D'] = 500;
roman['M'] = 1000;

int rvalue[3];
while (gets(str) && str[0] != '#') {
int size = 0, count = 0, sum = 0;
memset(visit, 0, sizeof(visit));
for (int i = 0; str[i]; ++ i) {
if (str[i] == '+' || str[i] == '=') {
buf[size ++][count] = 0;
count = 0;
}else {
buf[size][count ++] = str[i];
if (!visit[str[i]]) {
visit[str[i]] = 1;
maps[sum ++] = str[i];
}
}
}buf[size ++][count] = 0;

memset(first, 0, sizeof(first));
for (int i = 0; i < 3; ++ i) {
rvalue[i] = 0;
for (int j = 0; buf[i][j]; ++ j) {
if (buf[i][j+1] && roman[buf[i][j]] < roman[buf[i][j+1]])
rvalue[i] -= roman[buf[i][j]];
else rvalue[i] += roman[buf[i][j]];
}
first[buf[i][0]] = 1;
}

if (rvalue[0]+rvalue[1] == rvalue[2])
printf("Correct ");
else printf("Incorrect ");

ans = 0;
memset(used, 0, sizeof(used));
dfs(0, sum);
if (ans > 1)
printf("ambiguous\n");
else if (ans == 1)
printf("valid\n");
else printf("impossible\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: