zoukankan      html  css  js  c++  java
  • Luogu P3952时间复杂度

    一个错误的代码

    • 没有用栈 : 之前的循环如果没有执行,down = 0,会对后面产生影响,down实际上不需要

    写了将近两个小时。。。郁闷

    #include<cstdio>
    #include<algorithm>
    #include<locale>
    #include<cstring>
    #include<queue>
    #define N 1000001
    using namespace std;
    int stk[110],u[30],top;
    int L,t;
    int output[110];
    int main()
    {
    	freopen("in.txt","r",stdin);
    	scanf("%d",&t);
    	for(int k = 1;k <= t;++k)
    	{
    		char cmd[11];
    		int cnt = 0,ans,down = 1,complex = 0,maxc = -1;
    		memset(u,0,sizeof(u));
    		scanf("%d",&L);
    		scanf("%s",cmd);
    		if(cmd[2] == '1')
    		{
    			ans = 0;
    		}
    		else
    		{
    			int i = 4;
    			ans = 0;
    			while(isdigit(cmd[i]))
    			{
    				ans = ans*10 + cmd[i++] - 48;
    			}
    		}
    		getchar();
    		for(int i = 1; i <= L; ++i)
    		{
    			gets(cmd);
    			int x = 0,y = 0;
    			if(cmd[0] == 'F' && down == 1)
    			{
    				++cnt;
    				int tx = 4,ty = 6;
    				if(isdigit(cmd[4]))
    				{
    					while(cmd[tx] != ' ')
    					{
    						x = x*10 + cmd[tx++] - 48;
    					}
    				}
    				else{
    					tx = 5;
    					x = N;
    				}
    				if(isdigit(cmd[tx + 1]))
    				{
    					ty = tx + 1;
    					while(cmd[ty] != ' ')
    					{
    						y = y*10 + cmd[ty++] - 48;
    					}
    				}
    				else
    				{
    					y = N;
    				}			
    				
    				
    				if(x == N){
    					down = 0;
    				}
    				else
    				{
    					if(y == N)
    					{
    						if(u[cmd[2] - 'a' + 1] == 0){
    							u[cmd[2] - 'a' + 1] = 1;
    							stk[++top] = cmd[2] - 'a' + 1;
    							complex++;
    						}
    						else
    						{
    							printf("Conflict
    ");
    							down = 0;
    							output[k] = -1;
    						}
    					}
    					else
    					{
    						if(x >= y) down = 0;
    						else if(x < y)
    						{
    							if(u[cmd[2] - 'a' + 1] == 0)
    							{
    								u[cmd[2] - 'a' + 1] = 1;
    								stk[++top] = cmd[2] - 'a' + 1;
    								complex++;
    							}
    							else
    							{
    								printf("Conflict
    ");
    								down = 0;
    								output[k] = -1;
    							}
    						}
    					}
    				}
    			}
    			else if(cmd[0] == 'E')
    			{
    				--cnt;
    				if(down == 1)
    				{
    					u[stk[top--]] = 0;
    					maxc = max(maxc,complex);
    					complex = 0;
    				}
    				//printf("cnt--,%d
    ",cnt);
    			}
    			else if(down == 0)
    			{
    				++cnt;
    				maxc = max(maxc,complex);
    				if(maxc == ans)
    				{
    					output[k] = 1;
    				}
    				else
    				{
    					output[k] = 0;
    				}
    			}			
    		}
    		maxc = max(maxc,complex);
    		if(maxc == ans)
    		{
    			output[k] = 1;
    		}
    		else
    		{
    			output[k] = 0;
    		}
    		if(cnt != 0) output[k] = -1,printf("cnt != 0 %d  
    ",cnt);
    	}
    	for(int i = 1;i <= t;++i)
    	{
    		if(output[i] == 1) printf("Yes
    ");
    		else if(output[i] == -1) printf("ERR
    ");
    		else printf("No
    ");
    	}
    	return 0;
    }
    

    脑子呢?

    决定放弃,参考Luogu上的题解(离线做法),要用栈!!!
    #include<cstdio>
    #include<stack>
    #include<string>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int maxl=105;
    
    int t,l,w;
    string o;
    string code[maxl];
    //一个函数来获取代码中的正整数
    //用于获得c串下标为x的中的正整数,我们将 F x 1 n 中的n也看作整数,有利于后续对循环的处理。
    //n也就是特判一下,其余的模拟快读就好了
    int sread(int &x,string c)
    {
    	int res=0;
    	int len=c.size();
    	while(c[x]<'0' || c[x]>'9'&&x<c.size())
    	{
    		if(c[x]=='n')
    		{
    			++x;
    			return 1000000;
    		}
    		++x;
    	}
    	while(c[x]>='0' && c[x]<='9')
    	{
    		res*=10;
    		res+=c[x]-'0';
    		++x;
    	}
    	return res;
    }
    //写一个函数以获取复杂度:
    int geto()
    {
    	int res=0,x=3;
    	int len=o.size();
    	if(o[2]=='n') res=sread(x,o);
    	else res=0;
    	return res;
    }
    

    然后开始模拟循环,同时判断语法是否有误,并计算复杂度。我们写一个int check()函数,结果用res保存,若返回值为-1,则代表有语法错误,否则代表代码复杂度。(当前复杂度用now保存)。

    首先考虑没有语法错误的情况:

    我们在模拟的时候,肯定需要一个栈s。
    遍历一遍代码:

    • 如果遇到了F,那么获取变量名,用k保存,获取 F x i j 中的 i j,分别用 a b 保存。将 k 进栈。
    • 如果 b<a ,那么没有进入循环。用一个 flag 来保存最早的没有没有进入的 k。如果都进入了,则flag为-1。
    • 如果 a<=b ,代表进入循环,此时若 b-a>1000 并且 flag 为 -1 ,则本层循环对复杂度有贡献,执行 now++ 操作。同时我们用 ef[26] 保存 now++ 时 k 的信息(ef[k]=true)。(在k出栈时now - -,ef[k]=false)并更新res。(res=max(res,now))

    如果遇到了E,那么同样获取变量名 k ,将k弹出(因为没有语法错误,栈一定不空)。同时判断 flag是否为 k ,若为 k ,则 flag=-1 代表已经出了没有贡献的循环。在判断k是否对复杂度有贡献,若有,则now-,ef[k]=false;

    最后return res;

    再来在此基础上考虑有语法错误的情况:
    • F 和 E 不匹配 (类似于括号匹配):
      ① F比E多,只需在k出栈时判断栈是否为空,若为空则有语法错误,直接return -1。
      ② F比E少,只需在遍历完代码后判断栈是否不为空,若不空则有语法错误,直接return -1。
    • 新建的变量与已经存在但未被销毁的变量重复:
      用一个bool数组 ins[26] 表示当前,哪些变量被用过。那么只需在原来的基础上:
      ① 在k入栈时,判断k是否已经被用过(即k是否在栈中),若用过则有语法错误,直接return -1。
      ② 在k出栈时,判断栈是否为空,若为空则有语法错误,直接return -1。
      分析到此结束。
    int check()
    {
    	int res=0,now=0;
    	int a,b,x;
    	stack<int> s;
    	int flag=-1;
    	bool ins[26]= {0};
    	bool ef[26]= {0};
    	for(int i=1; i<=l; i++)
    	{
    		if(code[i][0]=='F')
    		{
    			int k=code[i][2]-'a';
    			if(ins[k]) return -1;
    			s.push(k);
    			ins[k]=true;
    			x=4;
    			a=sread(x,code[i]);
    			b=sread(x,code[i]);
    			//printf("a:%d  b:%d
    ",a,b);
    			if(b-a>1000)
    			{
    				if(flag==-1)
    				{
    					now++;
    					res=max(res,now);
    					ef[k]=true;
    				}
    			}
    			if(a>b)
    			{
    				if(flag==-1) flag=k;
    			}
    		}
    		if(code[i][0]=='E')
    		{
    			if(s.empty()) return -1;
    			int k=s.top();
    			s.pop();
    			ins[k]=false;
    			if(flag==k) flag=-1;
    			if(ef[k])
    			{
    				ef[k]=false;
    				now--;
    			}
    		}
    	}
    	if(s.size()) return -1;
    	return res;
    }
    
    int main()
    {
    	scanf("%d",&t);
    	while(t--)
    	{
    		int ww;
    		scanf("%d ",&l); //选用getline(cin,s)读入一整行代码;
    		getline(cin,o);    //注意%d后的空格(输入中l后有一个空格)
    		w=geto();
    		for(int i=1; i<=l; i++) getline(cin,code[i]);
    		ww=check();
    		if(ww==-1) puts("ERR");
    		else
    		{
    			if(ww==w) puts("Yes");
    			else puts("No");
    		}
    	}
    }
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    利用Filter和拦截器,将用户信息动态传入Request方法
    Spring统一返回Json工具类,带分页信息
    ASP.NET MVC4 学习记录
    lightgbm 的简单实践案例
    numpy和pandas 各种比较常见的用法总结
    【数据预处理】如何将某一类别特征的极少数类别归为一类
    十大经典算法之Apriori 算法
    常用函数框架
    【解决方案】django初始化执行python manage.py migrate命令后,除default数据库之外的其他数据库中的表没有创建出来
    【解决方案】M2Crypto不支持python3
  • 原文地址:https://www.cnblogs.com/Zforw/p/10800224.html
Copyright © 2011-2022 走看看