【NOIP2017DIT2】时间复杂度

Description



Sample Input

8
2 O(1)
F i 1 1
E
2 O(n^1)
F x 1 n
E
1 O(1)
F x 1 n
4 O(n^2)
F x 5 n
F y 10 n
E
E
4 O(n^2)
F x 9 n
E
F y 2 n
E
4 O(n^1)
F x 9 n
F y n 4
E
E
4 O(1)
F y n 4
F x 9 n
E
E
4 O(n^2)
F x 1 n
F x 1 10
E
E

Sample Output

Yes
Yes
ERR
Yes
No
Yes
Yes
ERR

Hint

【输入输出样例 1 说明】
  第一个程序 i 从 1 到 1 是常数复杂度。
  第二个程序 x 从 1 到 n 是 n 的一次方的复杂度。
  第三个程序有一个 F 开启循环却没有 E 结束,语法错误。
  第四个程序二重循环,n 的平方的复杂度。
  第五个程序两个一重循环,n 的一次方的复杂度。
  第六个程序第一重循环正常,但第二重循环开始即终止(因为n远大于100,100大于4)。
  第七个程序第一重循环无法进入,故为常数复杂度。
  第八个程序第二重循环中的变量 x 与第一重循环中的变量重复,出现语法错误②,输出ERR。
【输入输出样例 2】
  见选手目录下的complexity/complexity2.in 和 complexity/complexity2.ans。
【数据规模与约定】
  对于 30%的数据:不存在语法错误,数据保证小明给出的每个程序的前 L/2 行一定
  为以 F 开头的语句,第 L/2+1 行至第 L 行一定为以 E 开头的语句,L<=10,若 x、y 均为整数,x 一定小于 y,且只有 y 有可能为 n。
  对于 50%的数据:不存在语法错误,L<=100,且若 x、y 均为整数,x 一定小于 y,且只有 y 有可能为 n。
  对于 70%的数据:不存在语法错误,L<=100。
  对于 100%的数据:L<=100。






非常无脑的模拟题。。。做这个题的时候心酸历程:50RE--->70WA--->90WA--->1000AC。主要的难度是对于题意的理解。

QWQ这道题使用的技巧是stack和queue的使用对于循环中题目说明的不常规现象的处理,还有如果F的个数!=E的个数,肯定是ERR啦www。还有对于题目输入的类似快读思想的读入和变量名字的判重(用桶装ASCLL码)

比如说这种:

F x 0 n
F y 233 n
F z 12 n
F k n 123 //从这里开始断开,此时O(n^3)
F b 12 56
E
F T 23 124
F o 233 4444
E
F B 322 3232
E
E //从这里重新开始计算 
F p 2 n
F e 222 2222 //常数复杂度
F a n 3 //继续断开
F c n 222
E
E

所以整个数据的输出应该是O(n^4) 。

接下来上代码:
//题解by disangan233 or Lixiuyu     
#include<bits/stdc++.h>      
using namespace std;
#define re register int     
string o,a[105];
int t,o1,o2,o3,judge[205],now;// judge判断变量 
stack<int>s,p;
inline int read(int w)//针对循环开始和结束2个量的读入 
{
	re luoyang=0;   
	char did=a[w][now];
	while(did==' ')
	did=a[w][++now];    
	if(did<'0'||did>'9')
	return 123456;   
	while(did>='0'&&did<='9')
	luoyang=luoyang*10+did-'0',did=a[w][++now];
	return luoyang;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		re bjjj=0;
		o1=o2=0;
		memset(judge,0,sizeof(judge));
		while(!s.empty())
		s.pop();   
		while(!p.empty())
		p.pop();//初始化    
		re l,bj=0;
		scanf("%d",&l);   
		getline(cin,o);
		re l1=o.length();
		if(o[3]=='1'&&o[4]==' ') o1=0;
		else //对 O(n^w) 的w读入 
		{
			re jss=4;
			char didd=o[++jss];
			while(didd>='0'&&didd<='9')
			o1=o1*10+didd-'0',didd=o[++jss];
		}   
//		cout<<o1<<endl;
		for(re i=1;i<=l;i++)   
		getline(cin,a[i]);//读代码 
		for(re i=1;i<=l;i++)   
		{
			re start,end;
			now=4;
			if(s.empty())//我也不知道为什么要打这个 
			{
				o3=0;
				while(!p.empty())
				p.pop();
			}
			if(a[i][0]=='F') //循环处理 
			{
				s.push(i);
				if(judge[char(a[i][2])])//变量名处理 
				{
					bj=1;break;
				}
				start=read(i);now++;end=read(i); 
//				cout<<start<<":"<<end<<endl;
				if(start>end)//无法进入循环 用p实现 
				p.push(i);
				else if(p.empty()&&start!=end)
				{
					if(end>=123456)//用123456取代n 
					o3++;
				}
				judge[char(a[i][2])]++;
			}
			else 
			{
				if(s.empty())//E的个数大于F 
				{
					cout<<"ERR"<<endl;
					bjjj=1;
					break;
			    }
				judge[char(a[s.top()][2])]--;
				if(!p.empty())//删除p的栈顶 
				if(p.top()==s.top())
				p.pop();
				s.pop();
				o2=max(o2,o3);//更新O2 
//				cout<<o2<<endl;
				o3--;
			}
		}
		if(!s.empty()&&!bjjj)
		{
			cout<<"ERR"<<endl;
			bjjj=1;
		}   
		if(!bjjj)   
		{
			o2=max(o2,o3);
			o3=0;
			if(o1==o2) cout<<"Yes"<<endl;
			else cout<<"No"<<endl;
//			cout<<o1<<" "<<o2<<endl;
		}   
	}
	return 0; 
}
PS:温馨提示:\stary 241QWQ

猜你喜欢

转载自blog.csdn.net/disangan233/article/details/80943114
今日推荐