考完研之后摆烂太长时间了,今天逼自己写一道大模拟

题目:
t1.png
t2.png
t3.png
t4.png

模拟题首先应该先理清思路,看看需要做哪些事情。

1、首先提高组选手应该有能力提取字符串中的信息,这一题可能有些麻烦,需要提取复杂度的次方,循环初始变量和结束变量,特别地,如果变量是n,返回一个大于100的数即可。

2、我们先把错误的情况给判断了:

(1)其实回头来想想,如果数据出现在某一段程序E比F多,这是错误情况,我并没有考虑,巧的是,并没有这样的数据。。。甚至洛谷的hack数据也没有。。。

(2)如果F和E的个数不等是错的,这个不用多说怎么做了吧。。

(3)如果重复调用变量则错误,这个怎么办?既然变量都是小写字母,我们可以开一个数组记录该变量是否用过。那怎样判断销毁的变量是什么呢?这里开一个栈就可以了,遇到F将变量入栈,遇到E则将栈顶变量出栈,再将数组改成为使用即可。

3、我们怎样记录n的个数?首先,请注意如果初始和结束变量都是n,这是Θ(1)的复杂度。那么排除这种情况,遇到n我们就可以计数。问题来了,这时遇到E,我们怎么知道结束的是带n的循环还是不带的呢?我们再开一个栈,如果是满足可以计数的情况,我们压一个东西进去(随便你,爱压啥压啥),不可以就压另一个东西进去。这个栈的栈指针和前一个栈总是处于同一个位置的,那么我们就可以判断,此时可以计数的循环是否已经结束,我们是不是要把次数复杂度减去1。

4、初始变量大于结束变量该怎么办?这种情况显然这个循环下面嵌套的所有循环都不能走了,我们可以拿一个变量,遇到这种情况就加一,结束这种情况就减一,等于0我们再继续。但是什么时候减1呢?这是个问题,因为你下面还写了很多循环,你得知道哪个E是结束这个玩意的啊。我们巧妙的把前面的栈和这个变量结合一下,当前面栈指针,假设是tot,和这个变量相等了,我们就可以减1了。如果不理解,可以自己举个例子玩一玩。

这4点想清楚,代码应该就可以出来了,再多注意细节即可。


但是细节十分繁琐,到最后敲了五个小时才ac这题
洛谷.png


附代码:

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <stack>
#include <sstream>
#include <cmath>
using namespace std;
string panduan(vector<string> v,bool youn,int input){
    map<string,int> dp;
    int output=0; bool dain=false;int maxout=0;
    int sumf=0,linshif=0,jianf=0,jiaf=0;
    bool zhixing=true;//f个数
    vector<string> st;
    for(int i=0;i<v.size();i++){
    string arr[4]={"","","",""};
    //cout<<"当前arr:"<<arr[0]<<" "<<arr[1]<<" "<<arr[2]<<" "<<arr[3]<<endl;
    int tempi=0;
    for(int j=0;j<v[i].length();j++){
            if(v[i][j]==' ') tempi++;
        else arr[tempi]+=v[i][j];
    }
    
    int f1=0,f2=0;
    if(arr[2]!="n"&&arr[3]!="n"){
        stringstream s1;
        s1<<arr[2];
        s1>>f1;
        stringstream s2;
        s2<<arr[3];
        s2>>f2;
    }
    if(arr[0]=="F"){
        sumf++;
        if(!zhixing) linshif++;
        if(dp.count(arr[1])) {
            if(dp[arr[1]]==1)
                return "ERR";
            
        }
        
        dp[arr[1]]=1;
        st.push_back(arr[1]);

        //cout<<arr[3]<<" "<<arr[2]<<endl;
        if(zhixing){
            if(jianf>0&&sumf!=0) {
                jiaf++;
                if(jiaf>jianf){
                     output-=jianf;
                     jianf=0;
                     jiaf=0;
                }
                
            }
            
            if(arr[3]=="n"&&arr[2]!="n"){
            dain=true;
            output++;
            //cout<<"当前output:"<<output<<endl;
            }else if(arr[2]=="n"&&arr[3]!="n"||f1>f2){
                zhixing=false;
                linshif=1;
            }
        }
    }else{
        sumf--;
        if(zhixing&&sumf!=0) jianf++;
        if(!zhixing) linshif--;
        if(linshif==0) zhixing=true;
        if(sumf==0){
            if(dain){
                maxout=maxout>output?maxout:output;
                //cout<<output<<maxout<<"asdas"<<endl;
            }
            
            output=0;
            jianf=0;
        }
        if(st.size()>0){
            dp[st[st.size()-1]]=0;
            st.pop_back();
        }
    }
}
output=maxout;
if(!dain) output=1;
//cout<<youn<<" "<<dain<<" "<<output<<" "<<input<<endl;

if(youn==dain&&output==input&&sumf==0) return "Yes";
if(sumf!=0) return "ERR";
else return "No";


}
int main(){
int cao;
cin>>cao;
while(cao--){
    vector<string> v;//存循环字符串
int n,input;//n行  input为时间复杂度内数字
bool youn=false;//判断当前时间复杂度是否有n
string tim;//时间串

cin>>n>>tim;
string tim2="";
//判断当前时间复杂度是否有n
if(tim[2]=='n'){
    youn=true;
    for(int i=4;i<tim.length()-1;i++){
        tim2+=tim[i];
    }
    stringstream stm;
    stm<<tim2;
    stm>>input;
}else input=1; 

getchar();
//读入循环串进v
for(int i=0;i<n;i++){
    string str;
    getline(cin,str);
    v.push_back(str);
}

cout<<panduan(v,youn,input)<<endl;


}

//system("pause");
return 0;
}