zoukankan      html  css  js  c++  java
  • POJ1363 Rails 验证出栈序列问题

    题目地址: http://poj.org/problem?id=1363

    此题只需验证是否为合法的出栈序列。

    有两个思路:
    1、每个已出栈之后的数且小于此数的数都必须按降序排列。复杂度O(n^2),适合人脑。


    //思路 1 不对!!!  

    例如 数据 ,               3 5 2 4 1              --------                正确答案为 no

     

    //貌似这个数据确实是no,当时想错了,后面的判断完不能标记为出栈,

    但是修改了下代码还是没过。。。

    附上修改后代码:

    //wrong      poj 1363
    //accepted   zoj 1259
    //accepted   uva 514
    #include<iostream>
    #include<cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1000+10;
    int main()
    {
    	int a[maxn];
    	//	int b[maxn];//不用保留是否出栈了
    	int n;
    	while(cin>>n && n!=0)
    	{
    		while(1)
    		{
    			memset(a,0,sizeof(a));
    			//	memset(b,0,sizeof(b));
    			int i,j;
    			int x;
    			cin>>a[1];
    			if(a[1]==0)
    				break;
    			for(i=2;i<=n;i++)
    				cin>>a[i];
    			int max;
    			int t=true;
    			for(i=1;i<=n;i++)
    			{
    				//	if(b[i]!=1)
    				//	{
    				//	b[i]=1;
    				max=a[i];
    				for(j=i+1;j<=n;j++)
    				{
    					if(a[j]<max)//if(a[j]<max&&b[j]!=1)
    					{
    						if(a[j]!=max-1)
    						{
    							t=false;
    							break;
    						}
    						else
    						{
    							max--;
    							//	b[j]=1;
    						}
    					}
    				}
    				//	}
    				if(t==false)
    					break;
    			}
    			if(t==false)
    				cout<<"No"<<endl;
    			else
    				cout<<"Yes"<<endl;
    		}
    		cout<<endl;
    	}
    	return 0;
    }


     

     

    2、另一个思路就是直接模拟入栈出栈过程。虽然模拟毫无技巧可言,但复杂度O(n),优于算法1。适合电脑。

    代码如下:


    [java] view plaincopy
     
    1. for(i = 0; i < N; i++){  
    2.     if(index < data[i]){  
    3.         while(index < data[i]){  
    4.             stack.push(++index);  
    5.         }  
    6.         stack.pop();  
    7.     } else if(stack != null && stack.peek().equals(new Integer(data[i]))){  
    8.         stack.pop();  
    9.     } else {  
    10.         flag = "No";  
    11.         break;  
    12.     }  
    13. }  
    14. <span style="font-size:18px;">题目只用于验证,倒不难,不过我想问如果让求出所有合法的出栈序列该怎么求????有高效的算法吗?</span>  

    ----------------------------------------------------------
    代码 按思路 1 做的,错误。。测试数据 ,3 5 2 4 1  正确答案应该是 no

    //wrong      poj 1363
    //accepted   zoj 1259
    //accepted   uva 514
    #include<iostream>
    #include<cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1000+10;
    int main()
    {
    	int a[maxn];
    	int b[maxn];
    	int n;
    	while(cin>>n && n!=0)
    	{
    		while(1)
    		{
    			memset(a,0,sizeof(a));
    			memset(b,0,sizeof(b));
    			int i,j;
    			int x;
    			cin>>a[1];
    			if(a[1]==0)
    				break;
    			for(i=2;i<=n;i++)
    				cin>>a[i];
    			int max;
    			int t=true;
    			for(i=1;i<=n;i++)
    			{
    				if(b[i]!=1)
    				{
    					b[i]=1;
    					max=a[i];
    					for(j=i+1;j<=n;j++)
    					{
    						if(a[j]<max&&b[j]!=1)
    						{
    							if(a[j]!=max-1)
    							{
    								t=false;
    								break;
    							}
    							else
    							{
    								max--;
    								b[j]=1;
    							}
    						}
    					}
    				}
    				if(t==false)
    					break;
    			}
    			if(t==false)
    				cout<<"No"<<endl;
    			else
    				cout<<"Yes"<<endl;
    		}
    		cout<<endl;
    	}
    	return 0;
    }
    
    

    ---------------------------------------
    课本 正确代码 ,较复杂。

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn=1000+10;
    int main()
    {
    	int n,p[maxn];
    
    	cin>>n;
    	while(n)
    	{
    		int x,max=0;
    		cin>>x;
    		while(x)
    		{
    			memset(p,0,sizeof(p));
    			bool valid=true;
    			for(int i=1;i<=n;i++)
    			{
    				if(valid)
    				{
    					bool ok=true;
    					for(int i=x+1;i<=max;i++)
    						if(p[i]==1)
    						{
    							ok=false;
    							break;
    						}
    					if(!ok)
    						valid=false;
    					else
    					{
    						max=(max>x?max:x);
    						p[x]=2;
    						for(int i=x-1;i>0 && !p[i];i--)
    							p[i]=1;
    					}
    				}
    				if(i<n)
    					cin>>x;
    			}
    			cout<<(valid ? "Yes" : "No")<<endl;
    			cin>>x;
    		}
    		cout<<endl;
    		cin>>n;
    	}
    	return 0;
    }
    

    ------------------------------------------------------------




  • 相关阅读:
    for循环
    3.9 作业
    while循环
    深浅拷贝
    条件与判断
    可变与不可变
    与用户交互与运算符
    垃圾回收机制
    【AC自动机】文本生成器
    【AC自动机】最短母串
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4477484.html
Copyright © 2011-2022 走看看