P3952 时间复杂度

题目 (毒瘤) 传送门:P3952 时间复杂度

1:输入有点难办。

首先是O(?)的输入:

定义temp【是常量型(0)/n^w型(1)】

定义sum存后面的数,与temp相结合就是它的复杂度了。

①.遇到)就结束了;

②.有^时,使temp=1。

③.遇到数字就存入sum即可。

void init(){
	char ch=getchar();
	while(true){
		if(ch==')')break;
		if(ch=='^')temp=1;
		if(ch<='9'&&ch>='0'&&temp==1){
			sum=sum*10+ch-'0';
		}
		if(ch<='9'&&ch>='0'&&temp==0){
			sum=ch-'0';
		}
		ch=getchar();
	}
	return;
}
然后是循环体【F x y z】的输入:

定义了sum1存y上的数字,sum2存z上的数字

x可用cin输入,不考虑空格;

y用了getchar,因为x后面会有空格,所以要把kg占据掉,以防影响到y的输入;如果sum1=0,即y为n,再输入一遍y来占据n后的空格,以免影响z的输入;

kg=getchar();
y=getchar();
while(y<='9'&&y>='0'){
	sum1=sum1*10+y-'0';
	y=getchar();
}
if(sum1==0){
	y=getchar();
}

z同理

z=getchar();
while(z<='9'&&z>='0'){
	sum2=sum2*10+z-'0';
	z=getchar();
}

2.接下来就分情况吧!

temp1指目前的循环体的复杂度是O(n^w)还是O(1);
temp3指最终的循环体的复杂度是O(n^w)还是O(1);
temp2记录E的数量是否多余F的数量;
error是否输出ERR;
ans最终的复杂度

tim记录循环已经不能进入。
如:【F x 10 2 】之后循环就已经不能进入了;直到这一个循环体被E掉,tim还原;

cnt记录这一整个循环的复杂度,若为O(1),cnt*=1;若为O(n),cnt+=1;

num是循环体的个数,如果E的个数与F的个数不匹配,即最终的num>0,输出ERR;

f[x]判断变量x是否被用。

①F (i 常数 n) --> O(n^1);

②F (i n 常数) --> O(1),tim=num;

③F (i n n) --> O(1);

④F (i 常数 常数) --> O(1),如果 左>右,tim=num;

Code follow:

#include<bits/stdc++.h>
using namespace std;
int f[500];
char bj[500];
int m,T,cnt,sum,temp,num,ans,error,temp1,temp2,temp3;//循环复杂度,猜测复杂度,常数还是n的,是否结束; 
int tim;
void init(){
	char ch=getchar();
	while(true){
		if(ch==')')break;
		if(ch=='^')temp=1;
		if(ch<='9'&&ch>='0'&&temp==1){
			sum=sum*10+ch-'0';
		}
		if(ch<='9'&&ch>='0'&&temp==0){
			sum=ch-'0';
		}
		ch=getchar();
	}
	return;
}

int main()
{
	cin>>T;
	while(T--){
		ans=0;
		cnt=0;
		sum=0;
		temp=0;
		error=0;
		num=0;
		tim=0;
		temp1=0;
		temp2=0;
		temp3=0;
		memset(f,0,sizeof f);
		memset(bj,0,sizeof bj);
		cin>>m;
		init();
		for(int i=1;i<=m;i++){
			char ch;
			cin>>ch;
			if(ch=='F'){

				int sum1=0,sum2=0;
				char x,kg,y,z;
				cin>>x;
				kg=getchar();
				y=getchar();//输入y;
				while(y<='9'&&y>='0'){
					sum1=sum1*10+y-'0';
					y=getchar();
				}
				if(sum1==0){
					y=getchar();
				}
				z=getchar();//输入z 
				while(z<='9'&&z>='0'){
					sum2=sum2*10+z-'0';
					z=getchar();
				}
			
				if(num==0){
					temp1=0;
				}	
				if(f[x]==1){//变量重名; 
					error=1;
				}
				bj[++num]=x;
				f[x]=1;
				if(tim>0){
					continue;
				}		
				//F (i n n)  -->  O(1)
				if(sum1==0&&sum2==0){
					if(cnt==0)cnt=1;
					cnt*=1;
				}
				// F (i 常数 n)  --> O(n^1);
				if(sum1!=0&&sum2==0){
					if(temp1==0){
						cnt=1;
						temp1=1;
						continue;
					}
					cnt+=1;
				}
				//F (i n 常数)  --> O(1);
				if(sum1==0&&sum2!=0){
					if(cnt==0)cnt=1;
					cnt*=1;
					tim=num;
				}
				//F (i 常数 常数)  --> O(1)
				if(sum1!=0&&sum2!=0){
					if(sum1>sum2){
						tim=num;
					}
					if(cnt==0)cnt=1;
					cnt*=1;
				}
			}
			if(ch=='E'){
				if(i==1){
					error=1;
					break;
				}
				if(i!=1){
					f[bj[num]]=0;
					num--;

					if(num<0){
						num=0;
						temp2=1;
					}
					if(cnt>=ans){
						ans=cnt;
						temp3=temp1;
					}
					if(tim==0){
						cnt--;
					}
					if(num<tim){
						tim=0;
					}	
					if(cnt<0)cnt=0;
				}
			}
		if(error==0){
			if(ans==0||num>0||temp2==1){
				cout<<"ERR"<<endl;
			}
			else if(temp!=temp3){
				cout<<"No"<<endl;
			}
			else if(temp==0){
				if(ans==sum)cout<<"Yes"<<endl;
				else cout<<"No"<<endl;
			}
			else{
				if(ans==sum)cout<<"Yes"<<endl;
				else cout<<"No"<<endl;
			}
		}
		if(error==1){
			cout<<"ERR"<<endl;
		}
	}
	fclose(stdout);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值