UVA 185(暴力DFS)

本文介绍了一个程序,该程序能够解析并验证罗马数字的加法运算是否正确,并通过回溯算法来确定这些罗马数字对应的阿拉伯数字是否存在唯一解、多解或无解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

  Roman Numerals 

 

The original system of writing numbers used by the early Romans was simple but cumbersome. Various letters were used to represent important numbers, and these were then strung together to represent other numbers with the values decreasing monotonically from left to right. The letters they used and the numbers that were represented are given in the following table.

 

I1 V5
X10 L50
C100 D500
M1000   

Thus 1993 was written as MDCCCCLXXXXIII. This system was then superseded by a partially place-oriented system, whereby if the above rule of decreasing values was broken, it meant that the immediately preceding (lower) value was deemed to be `negative' and was subtracted from the higher (out of place) value. In this system 1993 was usually written as MCMXCIII. There is still some controversy as to which letters could precede which other letters, but for the purposes of this problem we will assume the following restrictions:

 

1.
A letter from the left column can never appear more than three times in a row, and there can never be more than one other occurrence of that letter.

 

2.
A letter from the right column can never appear more than once.

 

3.
Once a letter has been used in a `negative' position, all subsequent characters (apart from the one immediately following) may not be greater than that character.

Thus we could write MXMIII for 1993 or CCXCIV for 294, however we could not write ILV for 54, nor could we write LIL for 99. Note that 299 could be written as CCXCIX or CCIC

 


Given a Roman sum, we can either interpret it as such or as an encoding of an Arabic sum. Thus V+V=X could be interpreted as an ambiguous encoding of an Arabic sum with V $\in$ {1, 2, 3, 4} and X = 2 * V. Similarly, X+X=XX could be interpreted as a correct Roman sum but an impossible Arabic encoding (apart from the trivial encoding X = 0) and XX+XX=MXC as an incorrect Roman sum, but a valid encoding with M = 1, X = 9, and C = 8.

 


Write a program that will read in sums in Roman numerals and determine whether or not they are correct as Roman sums and also whether they are impossible, ambiguous or valid as Arabic encodings. Assume that zero will never appear on its own or as a leading digit, and that no two Roman numerals map onto the same Arabic digit.

 

Input 

Input will consist of a series of lines, each line consisting of an apparent Roman sum, i.e. a valid Roman number, a plus sign ( + ), another valid Roman number, an equal sign ( = ) and another valid Roman number. No Roman number will contain more than 9 letters. The file will be terminated by a line consisting of a single  # .

 

Output 

Output will consist of a series of lines, one for each line of the input, and each containing two words. The first word will be one of ( Correct, Incorrect ) depending on whether the Roman sum is or is not correct. The second word will be separated from the first by exactly one space and will be one of the set (impossible, ambiguous, valid) depending on the Arabic sum.

 

Sample input 

 

V+V=X
X+X=XX
XX+XX=MXC
#

 

Sample output 

 

Correct ambiguous
Correct impossible
Incorrect valid

 

题意:分两步,第一步判断输入的罗马数字运算结果对不对。第二步,如果每个字母可以用0-9代替,且不同字母不能重复,且有前导零不考虑。判断有一种还是多种还是没有能使得运算结果正确的答案。

思路:

#include <stdio.h>
#include <string.h>

char c[105];
int v[777];
int vv[777];
int vis[777];
int visn[10];
int vvv[10];
int vvvn;
int judge2;
char num[3][11];
void tra() {
    judge2 = 0;
    vvvn = 0;
    memset(vv, 0, sizeof(vv));
    memset(vvv, 0, sizeof(vvv));
    memset(vis, 0, sizeof(vis));
    memset(visn, 0, sizeof(visn));
    int nu = 0;
    int nul = 0;
    memset(num, 0, sizeof(num));
    for (int i = 0 ; i <= strlen(c); i ++) {
	if (c[i] == '+' || c[i] == '=' || c[i] == '\0') {
	    num[nul ++][nu] = '\0';
	    nu = 0;
	    continue;
	}
	if (vis[c[i]] == 0)
        {
	   vis[c[i]] = 1;
	   vvv[vvvn ++] = c[i];
	}
	num[nul][nu ++] = c[i];
    }
}
int judge1() {
    int numm[3];
    numm[0] = numm[1] = numm[2] = 0;
    for (int k = 0; k < 3; k ++) {
	for (int i = 0; i < strlen(num[k]); i ++) {
	    if (v[num[k][i + 1]] <= v[num[k][i]] || i == strlen(num[k]) - 1)
		numm[k] += v[num[k][i]];
	    else
		numm[k] -= v[num[k][i]];
	}
    }
    if (numm[0] + numm[1] == numm[2])
	return 1;
    else
	return 0;
}

void dfs(int nn)
{
    if (judge2 == 2)
	return;
    if (nn == vvvn) {
	int numm[3];
	numm[0] = numm[1] = numm[2] = 0;
	for (int k = 0; k < 3; k ++) {
	    for (int j = 0; j < strlen(num[k]); j ++) {
		numm[k] = numm[k] * 10 + vv[num[k][j]];
	    }
	}
	if (numm[0] + numm[1] == numm[2]) {
	    judge2 ++;
	}
	return;
    }
    for (int i = 0; i <= 9; i ++) {
	if (!visn[i]) {
	    vv[vvv[nn]] = i;
	    int bo = 0;
	    if (!vv[vvv[nn]]) {
		for (int j = 0; j < 3; j ++) {
		    if (num[j][0] == vvv[nn] && strlen(num[j]) > 1) {
			bo = 1;
			break;
		    }
		}
	    }
	    if (bo)
		continue;
	    visn[i] = 1;
	    dfs(nn + 1);
	    visn[i] = 0;
	}
    }
}
int main()
{
    v['I'] = 1; v['V'] = 5; v['X'] = 10; v['L'] = 50;
    v['C'] = 100; v['D'] = 500; v['M'] = 1000;
    while (gets(c) != NULL && c[0] != '#') {
	tra();
	dfs(0);
	if (judge1())
	    printf("Correct ");
	else
	    printf("Incorrect ");
	if (judge2 == 0)
	    printf("impossible\n");
	if (judge2 == 1)
	    printf("valid\n");
	if (judge2 == 2)
	    printf("ambiguous\n");
    }
    return 0;
}


第一步好处理。。把每个罗马数字转换为数字比较即可

 

第二步就是暴力。每个字母0-9暴力,如果遇到两种情况就可以直接结束。


 

内容概要:本文深入解析了扣子COZE AI编程及其详细应用代码案例,旨在帮助读者理解新一代低门槛智能体开发范式。文章从五个维度展开:关键概念、核心技巧、典型应用场景、详细代码案例分析以及未来发展趋势。首先介绍了扣子COZE的核心概念,如Bot、Workflow、Plugin、MemoryKnowledge。接着分享了意图识别、函数调用链、动态Prompt、渐进式发布及监控可观测等核心技巧。然后列举了企业内部智能客服、电商导购助手、教育领域AI助教金融行业合规质检等应用场景。最后,通过构建“会议纪要智能助手”的详细代码案例,展示了从需求描述、技术方案、Workflow节点拆解到调试与上线的全过程,并展望了多智能体协作、本地私有部署、Agent2Agent协议、边缘计算插件RAG等未来发展方向。; 适合人群:对AI编程感兴趣的开发者,尤其是希望快速落地AI产品的技术人员。; 使用场景及目标:①学习如何使用扣子COZE构建生产级智能体;②掌握智能体实例、自动化流程、扩展能力知识库的使用方法;③通过实际案例理解如何实现会议纪要智能助手的功能,包括触发器设置、下载节点、LLM节点Prompt设计、Code节点处理邮件节点配置。; 阅读建议:本文不仅提供了理论知识,还包含了详细的代码案例,建议读者结合实际业务需求进行实践,逐步掌握扣子COZE的各项功能,并关注其未来的发展趋势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值