CCF201803-3 URL映射(大模拟)

传送门:CCF201803-3 URL映射

做的第一道大模拟,代码一小时,debug四小时,很难受。

总的来说不是一道很麻烦的题,但有一些坑需要说明:

  1. 除了最后一个参数为时,规则末尾有无‘/’是不同的;
  2. 有可能出现空规则,即单独一个‘/’;
  3. 若一个url满足多个规则,按照输入时的顺序输出第一个;
  4. 类型参数需要抹去前导零。

最自闭的一个坑,花了两个多小时才找出来的,是我下意识使用了map作为存储规则与规则名称的结构。对,就是map,first用来存规则,second用来存规则名称。喝喝,看起来不用开两个数组很省事,实际上暗藏杀机,map事实上是排好序了的。。。这样会对上面的第三点产生影响。但用map也不是不可以,据我所知有C++11有一种map叫unordered_map,应该可以解决顺序的问题。

根据如上所述需要注意的点,我编了个样例,可以测试一下:

!样例输入

7 7
/articles/2003/ special_case_2003
/articles/ year_archive_1
/articles/// month_archive
/articles//// article_detail
/static/ static_serve
/a const_string
/ empty
/articles/2004/
/articles/2004/06
/articles/1985/09/aloha/
/articles/hello/
/static/js/jquery.js
/a
/

!样例输出

404
404
article_detail 1985 9 aloha
404
static_serve js/jquery.js
const_string
empty

下面上代码:

#include 
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int max0 = 128;
int n, m;
string s1[max0], s2[max0]; //规则及规则名
string sec[max0][max0]; //第i条规则的第j个参数
bool endflag[max0]; //规则是否以'/'结尾

void read()
{
    cin >> n >> m;
    for(int i = 0; i < n; ++i)
    {
        cin >> s1[i] >> s2[i];
        int cnt = 0;
        for(int j = 1; j < s1[i].size(); ++j)
        {
            if(s1[i][j] == '/')
            {
                ++cnt;
                if(j == s1[i].size()-1)
                    endflag[i] = 1;
                continue;
            }
            sec[i][cnt] += s1[i][j];
        }
    }
}

void search(string s)
{
    for(int i = 0; i < n; ++i)
    {
        vector  ans;
        int cnt = 0, j = 1;
        bool isAns = true;
        while(!sec[i][cnt].empty())
        {
            if(j == s.size())
            {
                isAns = false;
                break;
            }
            string currule = sec[i][cnt], ssec = "";
            if(currule == "")
            {
                while(j < s.size())
                {
                    if(s[j] == '/')
                    {
                        ++j;
                        break;
                    }
                    if(s[j] > '9' || s[j] < '0')
                        isAns = false;
                    ssec += s[j++];
                }
                if(!isAns)
                    break;
                while(ssec[0] == '0')
                    ssec.erase(ssec.begin());
                ans.push_back(ssec);
            }
            if(currule == "")
            {
                while(j < s.size())
                {
                    if(s[j] == '/')
                    {
                        ++j;
                        break;
                    }
                    ssec += s[j++];
                }
                ans.push_back(ssec);
            }
            if(currule == "")
            {
                while(j < s.size())
                    ssec += s[j++];
                ans.push_back(ssec);
            }
            if(currule[0] != '<')
            {
                while(j < s.size())
                {
                    if(s[j] == '/')
                    {
                        ++j;
                        break;
                    }
                    ssec += s[j++];
                }
                if(sec[i][cnt] != ssec)
                {
                    isAns = false;
                    break;
                }
            }
            ++cnt;
        }
        if(j < s.size())
            isAns = false;
        if(cnt && isAns && sec[i][cnt-1] != "")
        {
            bool sendflag = false;
            if(s[j-1] == '/')
                sendflag = true;
            if(endflag[i] != sendflag)
                isAns = false;
        }
        if(isAns)
        {
            cout << s2[i];
            for(int k = 0; k < ans.size(); ++k)
                cout << ' ' << ans[k];
            cout << '\n';
            return;
        }
    }
    cout << "404\n";
}

void solve()
{
    for(int i = 0; i < m; ++i)
    {
        string s;
        cin >> s;
        search(s);
    }
}

int main()
{
    read();
    solve();
    return 0;
}

 

你可能感兴趣的:(CCF,CSP认证题解)