
有一个形似央视大楼(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;
}
}