zoukankan      html  css  js  c++  java
  • UVA 185(暴力DFS)

      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.

     

    I 1   V 5
    X 10   L 50
    C 100   D 500
    M 1000      

    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] == '') {
    	    num[nul ++][nu] = '';
    	    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
    ");
    	if (judge2 == 1)
    	    printf("valid
    ");
    	if (judge2 == 2)
    	    printf("ambiguous
    ");
        }
        return 0;
    }


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

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


  • 相关阅读:
    js 读取XML
    JavaScript DOM 交换节点笔记
    JDBC学习总结 -- JDBC 快速入门 教程
    SQL 语句易错点讲解
    JAVA 他人博客收藏 (To be continue)
    <<MYSQL必知必会>> 入坑指南
    OpenGL 纹理学习总结
    BZOJ 3456 NTT图的计数 容斥
    洛谷1002 容斥原理+dfs OR DP
    51nod1565 FFT
  • 原文地址:https://www.cnblogs.com/pangblog/p/3253676.html
Copyright © 2011-2022 走看看