题目:https://www.patest.cn/contests/gplt/L2-004
转自:http://blog.csdn.net/dengkuomin/article/details/61916165
//http://blog.csdn.net/dengkuomin/article/details/61916165
//这位博主这段写的真棒,非常简洁的写法
#include<cstdio>
#include<iostream>
#define inf 0x3f3f3f3f
const int maxn=100001;
using namespace std;
int a[maxn],t;
bool f(int l,int r,int k)///遍历
{
if(l>=r) return true;///数组出界
int s=a[l],i;
bool p,q;
for(i=l+1; i<=r+1; i++)
{
p=q=true;
for(int j=i; j<=r; j++)///右子树
if(k?s>a[j]:s<=a[j])
{p=false; break;}
for(int j=i-1; j>l; j--)///左子树
{
if(k?s<=a[j]:s>a[j])
{q=false; break;}
}
if(q&&p) break; //遍历到一半停止,发现第一个循环,右边都并非大于a[j],然后左边都不小于等于a[j]。否则的话从这就断了
}
cout<<i<<endl;
if(p&&q){
cout<<"break="<<i<<endl;
return f(l+1,i-1,k)&&f(i,r,k);///进一步遍历左右子树
}
else return false;
}
void shuchu(int l,int r,int k)
{
if(l>r) return;
if(l==r)
{printf(++t==1 ? "%d" :" %d",a[l]); return;}
int s=a[l],i;
bool p,q;
for(i=l+1; i<=r+1; i++)
{
p=q=true;
for(int j=i; j<=r; j++)///左子树
if(k?s>a[j]:s<=a[j])
{p=false; break;}
for(int j=i-1; j>l; j--)///右子树
if(k?s<=a[j]:s>a[j])
{q=false; break;}
if(q&&p) break;
}
shuchu(l+1,i-1,k);
shuchu(i,r,k);
printf(++t==1 ? "%d" :" %d",s);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
int t=0;
if(f(0,n-1,1)){ //bst
printf("YES\n");
shuchu(0,n-1,1);
}
else if(f(0,n-1,0)){ //镜像
printf("YES\n");
shuchu(0,n-1,0);
}
else printf("NO");
printf("\n");
return 0;
}