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.
    
     */
  • 相关阅读:
    HDU 5585 Numbers
    HDU 3308 LCIS
    POJ 2991 Crane
    POJ 1436 Horizontally Visible Segments
    POJ 3667 Hotel
    HaiHongOJ 1003 God Wang
    【SDOI 2008】 递归数列
    5月19日省中提高组题解
    【HDU 1588】 Gauss Fibonacci
    【POJ 3233】Matrix Power Series
  • 原文地址:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1361.html
Copyright © 2011-2022 走看看