现在的位置: 首页 > 综合 > 正文

POJ 3794 Extended Normal Order Sort 解题报告

2014年02月07日 ⁄ 综合 ⁄ 共 3199字 ⁄ 字号 评论关闭

这道题确实是正常人不适宜做。不过也可以作为代码严谨程度的考验。

我的解法实现相当混乱,无暇修改了,写这篇解题报告的目的有三:一是记录下自己的解题,二是附录相关的测试数据,可能会方便到一些同学。

这道题其实题目描述得挺准确的,没有特别不可理解的地方,比如“0+1”和“1”比较,就是如题所述,比较0和1,前者小于后者即可,测试数据并无异常。

需要注意的是

1.涉及到数字比较,不能懒得直接用int类型,数字是可以任意长度的,需要按照字符串的格式,依次比较正负,长度,逐位比较。

2.先预处理会简单很多,不然像我这样需要考虑很多边边角角。

解题报告可参考http://blog.csdn.net/ederick/article/details/7244985,更为简洁。

测试数据如下:

[input]

10
x-3 X0001
123-456-7890 123+456+7890
xYz000123J XyZ+123j
#$%^&*[]- abcdefgh
Abc47jKL+00123 ABC+47jkL123
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
X+0000000000000000000000000000000000000000000000000 x-000000000000000000000000
11111111111111111111111111111111111111111111111111111111 99999999999999999999999999999999999999999999999
abc[ ABC{
#$%^&*(){}00001234#$%^&*(){}00001234 #$%^&*(){}1234#$%^&*(){}123

[output]

1 -1
2 1
3 0
4 -1
5 0
6 0
7 0
8 1
9 -1
10 1

我的程序(accepted):

#include <iostream>
#include <string>
using namespace std;

string extractword(string str, int index, bool afterdigit, int& step, bool& isdigit, int& digit, bool& neg)
{
    string word;
    neg = false;
    isdigit = false;
    digit = 0;
    step = 0;
    bool effective = false;
    bool repeatedzero = false;
    if(!afterdigit)
    {
        effective = true;
    }
    for(int i = index; i < str.length(); ++i)
    {
        step++;
        if(str[i] == '-' || str[i] == '+')
        {
            if(i == index)
            {
                if(!afterdigit && str[i] == '-')
                {
                    neg = true;
                }
            }
            else
            {
                if(isdigit & neg)
                {
                    digit *= -1;
                }
                step--;
                return word;
            }
            if(!afterdigit && i + 1 < str.length() && (str[i + 1] <= '9' && str[i + 1] >= '0'))
            {
                continue;
            }
        }
    
        if(str[i] <= '9' && str[i] >= '0')
        {
            if(!isdigit)
            {
                if(i != index && !(i == index + 1 && (str[index] == '+' || str[index] == '-') && effective))
                {
                    step--;
                    return word;
                }
            }
            isdigit = true;
            afterdigit = true;
            digit = digit * 10 + str[i] - '0';
            if(str[i] == '0' && i + 1 < str.length() && (str[i + 1] <= '9' && str[i + 1] >= '0'))
            {
                continue;
            }
        }
        
        if(str[i] <= 'Z' && str[i] >= 'A')
        {
            str[i] += 'a' - 'A';
        }
        
        if(str[i] <= 'z' && str[i] >= 'a')
        {
            if(isdigit)
            {
                if(neg)
                {
                    digit *= -1;
                }
                step--;
                return word;
            }
        }
        word.push_back(str[i]);
    }
    if(isdigit && neg)
    {
        digit *= -1;
    }
    return word;
}

int compare(string a, string b)
{
    bool afterdigita = false, afterdigitb = false;
    
    int i = 0, j = 0;
    while(i < a.length() && j < b.length())
    {
        int stepa = 0, stepb = 0;
        bool isdigita = false, isdigitb = false;
        bool isnega = false, isnegb = false;
        int digita = -1, digitb = -1;
        string worda = extractword(a, i, afterdigita, stepa, isdigita, digita, isnega);
        string wordb = extractword(b, j, afterdigitb, stepb, isdigitb, digitb, isnegb);
        
        if(isdigita)
        {
            afterdigita = true;
        }
        else
        {
            afterdigita = false;
        }
        if(isdigitb)
        {
            afterdigitb = true;
        }
        else
        {
            afterdigitb = false;
        }
        if(isdigita && isdigitb)
        {
            if(isnega && !isnegb)
            {
                if(worda == "0" && wordb == "0")
                {
                    return 0;
                }
                else
                {
                    return -1;
                }
            }

            if(isnegb && !isnega)
            {
                if(worda == "0" && wordb == "0")
                {
                    return 0;
                }
                else
                {
                    return -1;
                }
            }

            if(worda.length() != wordb.length())
            {
                if(isnega)
                {
                    return worda.length() < wordb.length() ? 1 : -1;
                }
                else
                {
                    return worda.length() < wordb.length() ? -1 : 1;   
                }
            }

            for(int i = 0; i < worda.length(); ++i)
            {
                if(worda[i] != wordb[i])
                {
                    if(isnega)
                    {
                        return (worda[i] - '0') < (wordb[i] - '0') ? 1 : -1;
                    }
                    else
                    {
                        return (worda[i] - '0') < (wordb[i] - '0') ? -1 : 1;   
                    }
                }
            }
            /*
            if(digita < digitb)
            {
                return -1;
            }
            else if(digita > digitb)
            {
                return 1;
            }
            */
        }
        else
        {
            if(worda < wordb)
            {
                return -1;
            }
            else if(worda > wordb)
            {
                return 1;
            }
        }
        i += stepa;
        j += stepb;
    }
    if(i < a.length())
    {
        return 1;
    }
    if(j < b.length())
    {
        return -1;
    }
    return 0;
}

int main()
{
    int N;
    cin>>N;
    for(int no = 0; no < N; ++no)
    {
        string a, b;
        cin>>a>>b;
        //cout<<"a: "<<a<<", b: "<<b<<endl;
        cout<<no + 1<<" ";
        cout<<compare(a, b)<<endl;
    }
    return 0;
}

抱歉!评论已关闭.