生命不息,奋斗不止

题解 CF21A 【Jabber ID】

2020-12-29 22:51:46


思路

这道题完全是一道字符串模拟的题。他的重点就在于我们如何把整个字符串 $s$ 分割成 $<username>$ , $<hostname>$ 以及 $[/resource]$ 我们不妨直接将整个输入进来的字符串 $s$ 用循环扫一遍,找到 $“@”$所在的位置。这就找到了 $<username>$。接着,我们可以将余下的部分扫一遍,如果发现有 $“.”$ ,那么就要看前一部分的长度。由于所有 $<hostname>$ 之间的字串最长不得超过16,所以我们就要判断前一段的字串是否合法。在结束时也要判断整个长度不得超过32

"蒟"例说明

例如本题的样例1,我们就可以分割成这样

mike|@|codeforces.com

当然,也不排除题目中没有的情况:

lbwnb|@|.com
         ↑  

$<hostname>$是不能直接以 $ . $ 开头的

代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    cin >> s;
    int nw = 0;//hostname的开头元素-1
    while(s[nw]!='@'){
        if(isalpha(s[nw]) || isalnum(s[nw]) || s[nw] == '_') nw++;
        else{//不合法
            cout << "NO" << endl;
            return 0;
        }
    }
    if(nw - 1 > 16 || nw - 1 < 1){//username长度是否合法
        cout << "NO" << endl;
        return 0;
    }
    if(s.size() - nw + 1 <= 0){//hostname长度是否合法
        cout << "NO" << endl;
        return 0;
    }

    int cnt = 0, acnt = 0, sta = -114514;
    for(int i = nw + 1; i < s.size(); i++){
        cnt++;
        if(s[i] == '.'){
            if(cnt <= 1 || cnt > 16){
                cout << "NO" << endl;
                return 0;
            }
            cnt = 0;
        } else if(isalnum(s[i]) || isalpha(s[i]) || s[nw] == '_'){
            continue;
        } else if(s[i] == '/'){
            if(cnt < 0 || cnt > 16){
                cout << "NO" << endl;
                return 0;
            } else {
                sta = i + 1;
                break;
            }
        } else {
            cout << "NO" << endl;
            return 0;
        }
    }
    if(sta != -114514)//确实有[/resource]
        for(int i = sta; i < s.size(); i++){
            if(isalnum(s[i]) || isalpha(s[i]) || s[nw] == '_') continue;
            else {
                cout << "NO" << endl;
                return 0;
            }
        }

    cout << "YES" << endl;
    return 0;
}