zoukankan      html  css  js  c++  java
  • 【算法学习笔记】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.
    
     */
  • 相关阅读:
    Cinema in Akiba(线段树)
    SGU
    632-掷骰子
    ZOJ
    nyoj 1129 Salvation(搜索)
    symbol table meaning
    C/C++编译和链接过程详解 (重定向表,导出符号表,未解决符号表)
    编译链接 C++
    while(cin.eof)出错 poj
    华为oj 购物单
  • 原文地址:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1361.html
Copyright © 2011-2022 走看看