考完研之后摆烂太长时间了,今天逼自己写一道大模拟
题目:
模拟题首先应该先理清思路,看看需要做哪些事情。
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这题
附代码:
#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;
}