Ball Aizu - 0033

题意:

有一个形似央视大楼(Orz)的筒,从A口可以放球,放进去的球可通过挡板DE使其掉进B裤管或C裤管里,现有带1-10标号的球按给定顺序从A口放入,问是否有一种控制挡板的策略可以使B裤管和C裤管中的球从下往上标号递增。 

输入:

第一行输入数据组数N。接下来N行为N组具体数据,每组数据中有10个整数,代表球的放入顺序。 

输出:

对于每组数据,若策略存在,输出YES;若不存在,输出NO。

思路:

由于本题数据很小,只有10个球,所以很多方法都可以,比如二进制枚举,比如开两个栈根据两个栈顶顶元素与下一个要放入的球比较大小决定下个球是否能放入放入哪个栈,当然做这道题的时候主要是为了练习深度搜索(DFS)。


AC代码:

第一种(栈):

#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include<stack>


using namespace std;
int t[11];
stack<int> a;
stack<int> b;
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
       while(!a.empty())
        a.pop();
       while(!b.empty())
        b.pop();
        int flag=0;
        memset(t,0,sizeof(0));
        for(int i=0;i<10;i++)
        {
            scanf("%d",&t[i]);
        }
       // sort(t,t+10,cmp);
        a.push(t[0]);
        b.push(0);
        for(int i=1;i<10;i++)
        {
            if(t[i]>a.top()&&t[i]<=b.top())
                a.push(t[i]);
            else if(t[i]<=a.top()&&t[i]>b.top())
                b.push(t[i]);
             else if(t[i]>a.top()&&t[i]>b.top())
             {
                 if(a.top()>b.top())
                  a.push(t[i]);
                 else
                    b.push(t[i]);
                    
             }
               
                else if(t[i]<=a.top()&&t[i]<=b.top())
              {
                  flag=1;
                  break;
              }
        }
        if(flag)
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl;






    }
}


AC代码:

第二种(二进制枚举);

#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include<stack>
#include<vector>


using namespace std;
int t[11];
vector<int>a;
vector<int>b;
int aa,bb;
bool solve()
{
      for(int i = 0 ; i< 1<<10 ;i++)
      {
          a.clear(),aa=0;
          b.clear(),bb=0;
        for(int j = 0 ; j < 10 ; j++)
        {
            if(i&(1<<j))
            a.push_back(t[j]);
            else
            b.push_back(t[j]);


        }
        int l1=a.size();//这里如果直接写成  for(int i=0;i<(a.size()-1);i++)就运行超时,莫名其妙????哪位大神解答一下!!
        int l2=b.size();
      for(int i=0;i<l1-1;i++)
      {
         if(a[i]>a[i+1])
              
          {
                 aa=1;break;
          }


      }


        for(int i=0;i<l2-1;i++)
      {
          if(b[i]>b[i+1])
          {
              bb=1;break;
          }


      }


      if(aa==0&&bb==0)
      {
          return true;
      }


    }


        return false;




}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        a.clear();aa=0;
        b.clear();bb=0;
        memset(t,0,sizeof(t));
        for(int i = 0 ; i < 10 ; i++)
        {
           scanf("%d",&t[i]);
        }


        if(solve())
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;


   }
}


AC代码:

第三种(深度搜索(DFS)):

//思路:先dfs出一个递增数组A,剩下的组成一个数组B,判断B数组是否递增即可。

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>

using namespace std;
int t[11];
int v[11];
void dfs(int x,int y)
{
    if(t[x]<t[y]&&y<10)
    {
        v[y]=1;
        dfs(y,y+1);
    }
    else if(t[x]>t[y]&&y<10)
    {
        dfs(x,y+1);
    }
}
int main()
{
    int n,flag=0;
    scanf("%d",&n);
    while(n--)
    {
        memset(t,0,sizeof(t));


        //初始化
        for(int i=0;i<10;i++)
            scanf("%d",&t[i]);
        for(int i=0;i<10;i++)//i<9??
        {
            memset(v,0,sizeof(v));
              v[i]=1;
             dfs(i,i+1);
          int aa=0;flag=0;
             for(int i=0;i<10;i++)
            {
                if(v[i]==0)
                {
                      if(aa>t[i])
                      {
                          flag=1;
                          break;
                      }
                      else
                        aa=t[i];
                }


            }
            if(flag==0)
            {
                cout<<"YES"<<endl;
                break;
            }


        }
            if(flag==1)
                cout<<"NO"<<endl;












    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值