[LUOGU] P3952 时间复杂度

其实,也没那么难写
这种模拟题,仔细分析一下输入格式,分析可能的情况,把思路写在纸上,逐步求精,注意代码实现

主要思路就是算一个时间复杂度,和给出的复杂度比较,这就先设计一个函数把给出的复杂度由字符串形式化为数字形式
然后开始分析,对于F:

  1. 检查变量合法
  2. 分类:常量-常量和n-n:O(1),常量-n:O(n),n-常量:无法进入,记为0,特殊标记一个slay
    3.压栈:栈内记录变量名和贡献的复杂度,用map标记变量为使用过
    对于E:
  3. 检查栈空
  4. 如果没有slay标记就更新答案
  5. 弹栈,清空变量使用

一个问题:ERR不能直接返回,剩下的程序还是要读完的

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<map>
using namespace std;
 
 
int n;
string ostring;

struct Node{
	string var;
	int o,slay;
	Node(string s="",int _=0,int l=0){var=s;o=_;slay=l;}	
};

int ans,cur;
Node sta[10000];
int top;
map<string,int> mp;
int checkO(string s){//return the O of s
	if(s=="O(1)") return 0;
	int ret=0,p=0;char c;
	while(c=s[p++],!isdigit(c));
	while(isdigit(c)){
		ret=ret*10+c-'0';
		c=s[p++];
	}
	return ret;
}

int push(string var,string st,string ed){
	if(mp[var]==1)return -1;
	
	mp[var]=1;
	if(st=="n"&&ed=="n") return 0;
	if(st=="n") return -2;//slay =1
	if(ed=="n") return 1;
	int l=0,r=0;
	int len=st.size();
	for(int i=0;i<len;i++){
		l*=10;
		l+=st[i]-'0';
	}
	len=ed.size();
	for(int i=0;i<len;i++){
		r*=10;
		r+=ed[i]-'0';
	}
	if(l<=r) return 0;
	else return -2;
}

int pop(){
	if(!top) return -1;
	Node tmp=sta[top--];
	mp[tmp.var]=0;
	if(!tmp.slay) ans=max(ans,cur);
	cur-=tmp.o;
}
	

int solve(int len){
	int fail=0;
	ans=0;cur=0;top=0;mp.clear();
	int tmp=0,sl=0;
	string s,var,st,ed;
	for(int i=1;i<=len;i++){
		sl=0;
		cin>>s;
		if(s=="F"){
			cin>>var>>st>>ed;
			tmp=push(var,st,ed);
			if(tmp==-1) fail=1;
			if(tmp==-2) sl=1,tmp=0;
			if(top>0) sl|=sta[top].slay;
			sta[++top]=Node(var,tmp,sl);	
			cur+=tmp;
		}else{
			tmp=pop();
			if(tmp==-1) fail=1;
		}
	}
	if(top) return -1;
	if(fail) return -1;
	return ans; 
}
 
int main(){
	int T;
	cin>>T;
	while(T--){
		top=0;ans=0;cur=0;
		cin>>n>>ostring;
		int aim=checkO(ostring); 
		int res=solve(n);
		if(res==-1) {puts("ERR");continue;}
		if(aim==res) {puts("Yes");continue;}
		puts("No");
	}
	return 0;
}
posted @ 2018-09-30 00:59  GhostCai  阅读(141)  评论(0编辑  收藏  举报