【算法学习笔记】50.字符串处理 SJTU OJ 1361 丁姐的周末

Description

丁姐来到了神秘的M78星云,为了成为和凹凸曼一样强大的男人有朝一日回到地球拯救世界,丁姐开始了刻苦的学习。但丁姐先要知道在M78星云上一周有多少天,这样他才能知道什么时候是周末可以带妹子出去玩。他找到一个老凹凸曼,但是老凹凸曼自己记性不太好,偶尔会告诉他错误的信息。

凹凸曼会告诉丁姐如下格式的信息:

Today is xxxday.

Yesterday was yyyend.

Tomorrow will be zzzday.

规则1: xxx/yyy/zzz为任意字符串,以day结尾的单词代表工作日,以end结尾的单词代表周末。

规则2: Today is xxxxx. 总是正确的。

规则3: Yesterday was xxxxx. 是正确的,当且仅当在上文中出现过xxxxx。

规则4: Tomorrow will be xxxxx. 是正确的,当且仅当在下文中出现过xxxxx。

规则5: xxxxx被认为是合法的一天,当且仅当至少有一句包含xxxxx的信息是正确的。

请你帮丁姐计算出在M78星云上一周有几天?周末有几天?

Input Format

第1行,一个数字n,表示总共有n条信息。

第2到n+1行,一条具体的信息。

Output Format

两个整数A和B,表示一周共有A天,周末有B天。

Sample Input

6
Today is sunday. // 工作日
Yesterday was friday. // 错误
Tomorrow will be ksnsend. // 错误
Yesterday was friday. // 工作日
Today is tuesdayend. // 周末
Yesterday was sunday. // 工作日,重复

Sample Output

3 1

Limit

n <= 1000

50%测试数据只有Today

思路很简单。就是很麻烦,条件很多容易出错。尤其是判断前后文的问题,要考虑字符串包含的特殊情况。

#include <iostream>
#include <cstdio>
#define MaxN 1000+10
using namespace std;


int day_len = 0;//存储day的个数
int end_len = 0;//存储end的个数
string ori[MaxN];//存数输入的原话
string inputs[MaxN];//存数day和end的名字 具体类型 用type存储

int weekdays[MaxN];//存储的是确定第i个day所用的是第几句话
int weekends[MaxN];//存储的是确定第i个end所用的是第几句话

int inputs_type[MaxN]; //存储每个输入的类型 0是day 1是end

int n;//一共有n句话

//判断是否在j之前出现过test
bool occur_formor(string test,int j,int type){
    for (int i = 1; i < j; ++i)
    {
        if(test == inputs[i] and type == inputs_type[i])
            return true;
    }
    return false;
}

//判断是否在j之后出现过test
bool occur_post(string test,int j,int type){
    if(type==1)
        test += "end";
    else
        test += "day";
    for (int i = j+1; i <= n; ++i)
    {
        if(ori[i]=="Today is "+test+".")
            return true;
        if(ori[i]=="Yesterday was "+test+".")
            return true;
        if(ori[i]=="Tomorrow will be "+test+".") 
            return true;
    }
    return false;
}

//判断是否出现过test+day
bool have_in_weekday(string test){
    
    for (int i = 0; i < day_len; ++i) //遍历所有的确定过的day
    {
        int id = weekdays[i];//得到确定那个day的inputs的编号
        if(inputs[id] == test and inputs_type[id]==0)
            return true;
    }
    return false;
}
//判断是否出现过test+end
bool have_in_weekend(string test){
    
    for (int i = 0; i < end_len; ++i)
    {
        int id = weekends[i];
        if(inputs[id] == test and inputs_type[id]==1)
            return true;
    }
    return false;
}

//尝试加入一个数i是句子编号 xxx是天的名字 type是种类
void add(int type, string xxx,int i){
    if(type==1 and !have_in_weekend(xxx)){
        weekends[end_len++] = i;
    }else if(type==0 and !have_in_weekday(xxx)){
        weekdays[day_len++] = i;
    }
    return;
}

string getXXX(string s,string seg){
    int start = s.find(seg)+seg.size(); 
    return s.substr(start, s.size()-4-start);
}

int main(int argc, char const *argv[])
{
    
    cin>>n;
    getchar();//去除回车

    //存储原始输入 以便处理"下文" 的条件
    for (int i = 1; i <= n; ++i)
    {
        getline(cin,ori[i]);
    }
    
    
    //开始处理输入
    for (int i = 1; i <= n; ++i)
    {
        string& s = ori[i]; 
        
        //根据前5个字符来判断输入的是今天 昨天 明天
        string flag = s.substr(0,5);//flag用于判断是哪种输入
        
        string xxx;//day或者end的名字
        
        int type;//记录 1是end 0是day
        
        //根据倒数第二个字符来判断输入天的类型
        if(s[s.size()-2]=='d')//xxxend.
            type = 1;//end是1
        else
            type = 0;//day是0
        
        //如果说的是今天
        if(flag=="Today"){
            xxx = getXXX(s,"Today is ");
            add(type,xxx,i);
        }else if(flag=="Yeste"){
            xxx = getXXX(s,"Yesterday was ");
            if(occur_formor(xxx,i,type))//如果前文提到过
                add(type,xxx,i);
        }else if(flag =="Tomor"){
            xxx = getXXX(s,"Tomorrow will be ");
            if(occur_post(xxx,i,type))//如果后文提到过
                add(type,xxx,i);
        }
        inputs_type[i] = type;
        inputs[i] = xxx;
    }

    cout<<end_len + day_len<<" "<<end_len<<endl;
    return 0;
}

/*
6
Today is sunday.
Yesterday was friday.
Tomorrow will be ksnsend.
Yesterday was friday.
Today is tuesdayend.
Yesterday was sunday.

 
2
Tomorrow will endday.
Today is enddayday.

 */
原文地址:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1361.html