ICPC Yokohama 2018 A. Digits Are Not Just Characters


Mr. Manuel Majorana Minore made a number of ?les with numbers in their names. He wants to have a list of the ?les, but the ?le listing command commonly used lists them in an order di?erent from what he prefers, interpreting digit sequences in them as ASCII code sequences, not as numbers. For example, the ?les file10, file20 and file3 are listed in this order.Write a program which decides the orders of ?le names interpreting digit sequences as numeric values.Each ?le name consists of uppercase letters (from ‘A’ to ‘Z’), lowercase letters (from ‘a’ to ‘z’), and digits (from ‘0’ to ‘9’).A ?le name is looked upon as a sequence of items, each being either a letter or a number. Each single uppercase or lowercase letter forms a letter item. Each consecutive sequence of digits forms a number item.Two item are ordered as follows.

  • Number items come before letter items.
  • Two letter items are ordered by their ASCII codes.
  • Two number items are ordered by their values when interpreted as decimal

numbers. Two ?le names are compared item by item, starting from the top, and the order of the ?rst di?erent corresponding items decides the order of the ?le names. If one of them, say A, has more items than the other, B, and all the items of B are the same as the corresponding items of A, B should come before.For example, three ?le names in Sample Input 1, file10, file20, and file3 all start with the same sequence of four letter items f, i, l, and e, followed by a number item, 10, 20, and 3, respectively. Comparing numeric values of these number items, they are ordered as file3 < file10 < file20.

输入

The input consists of a single test case of the following format.n s0 s1 . . . snThe integer n in the ?rst line gives the number of ?le names (s1 through sn) to be compared with the ?le name given in the next line (s0). Here, n satis?es 1 ≤ n ≤ 1000. The following n + 1 lines are ?le names, s0 through sn, one in each line. They have at least one and no more than nine characters. Each of the characters is either an uppercase letter, a lowercase letter, or a digit.Sequences of digits in the ?le names never start with a digit zero (0).

输出

For each of the ?le names, s1 through sn, output one line with a character indicating whether it should come before s0 or not. The character should be “-” if it is to be listed before s0; otherwise, it should be “+”, including cases where two names are identical.

样例输入1

2 
file10 
file20 
file3

样例输出1

+
-

样例输入2

11 
X52Y 
X 
X5 
X52 
X52Y 
X52Y6 
32 
ABC 
XYZ 
x51y 
X8Y 
X222

样例输出2

-
-
-
+
+
-
-
+
+
-
+

大意

字符串拆分成段,排序先后取决于第一个不同的段,而和长度无关;同一位置数字和数字比,字母和字母比,不同则数字在字母前面。

代码

#include 
#include 
#include 
#include 

using namespace std;

typedef struct strs {
    string str; // origin string
    int sector[10]; // value of each sector
    int type[10]; // 0 digit 1 alpha
                  // digit appears before alpha
    int num; // sum of sectors
    strs () {}
    strs (string strt, int* sec, int* tp, int n):str(strt), num(n) {
        for (int i = 0; i < n; i++) {
            sector[i] = sec[i];
            type[i] = tp[i];
        }
    }
} strstu;
strstu s0;

strstu getstr (string str) // cover string to strstu;
{
    int sector[10] = {0};
    int type[10] = {0};
    int num = 0;
    for (int i = 0; i < str.length(); i++)
        if (isalpha(str[i])) {
            type[num] = 1;
            sector[num++] = int(str[i]);
        } else {
            int n = 0;
            for (int j = i; ; j++) {
                if (isalpha(str[j]) || j == str.length()) {
                    sector[num++] = n;
                    i = j - 1;
                    //printf("%d ", n);
                    break;
                }
                n *= 10;
                n += str[j] - '0';
            }
        }
    return strstu(str, sector, type, num);
}

bool judge (strstu str) //before s0 return true
{
    int slen = str.num <= s0.num ? str.num : s0.num;
    int flag = 1;
    for (int i = 0; i < slen; i++) {
        if (s0.type[i] != str.type[i] || s0.sector[i] != str.sector[i])
            flag = 0;
        if (str.type[i] > s0.type[i]) return false;
        if (str.type[i] < s0.type[i]) return true;
        if (str.type[i] == s0.type[i] && str.sector[i] < s0.sector[i])
            return true;
        else if (str.type[i] == s0.type[i] && str.sector[i] > s0.sector[i])
            return false;
    }

    if (flag && str.num < s0.num) //shoter but have same header
        return true;
    
    return false;
}

int main()
{
    int n;
    string s, t;
    cin >> n;
    cin >> s;
    
    s0 = getstr(s);
    
    while (n--) {
        cin >> t;
        if (judge(getstr(t))) printf("-\n");
        else printf("+\n");
    }
    
    return 0;
}