深搜算法-1024

题意:给出一个序列,要你输出这个序列的前p个序列(若总排列w<p,则只需要输出w个)
排列方式: 序列为原序列的非减子序列, length从小到大, length相同的话,位置前的排在前面;
思路:判断如果搜索的是子序列的第一个元素,那么判断从原始序列开始到当前位置是否已经出现过该元素,若出现过则之前肯定搜索过该元素,则放弃该元素的搜索。第二个重判,当搜索的不是子序列的第一个元素时,则判断子序列的前一个元素对应原始序列的位置,然后从该位置下一个元素开始到到当前搜索的位置之前判断该元素是否出现过,如果出现过,说明该子串出现过重复的,则放弃该元素。
 #include<iostream>
#include<set>
 #include<cstring>
#define LL long long
  using namespace std;

 const int maxn=1010;
  LL a[maxn];
  LL ans[10000];
 int n,p,len;
 bool flag;

 set<LL>ssss;
 set<LL>::iterator it;

 void dfs(int cur,int cnt)
 {
     if(cnt>len)
         return ;
     ans[cnt]=a[cur];
    if(cnt==len)
     {
         for(int i=1;i<cnt;i++)
             cout<<ans[i]<<" ";
         cout<<ans[cnt]<<endl;
         flag=true;
        p--;
         return ;
     }
     //开始这个set是写在了函数外面,然后一直wa
    //写在外面,dfs操作的其实一直是同一个s,前面的可能也会被clear()
     set<LL>s;
    s.clear();
     for(int i=cur+1;i<=n;i++)
   {
    if(a[i]>=a[cur]&&p>0)
        {
            it=s.find(a[i]);
             if(it!=s.end())
                 continue;
             dfs(i,cnt+1);
             s.insert(a[i]);
         }
     }
 }

 int main()
 {
     while(cin>>n>>p)
     {
         for(int i=1;i<=n;i++)
             cin>>a[i];
         int m=0;         ssss.clear();
         for(int i=1;i<=n;i++)
        {
             it=ssss.find(a[i]);
           if(it!=ssss.end())
                continue;
            cout<<a[i]<<endl;
            ssss.insert(a[i]);
            m++;
             if(m>=p)
                 break;
         }
         p-=m;
         len=2;
         ssss.clear();
      while(p>0&&len<=n)
        {
            flag=false;
            ssss.clear();
             for(int i=1;i<=(n-len+1);i++)
             {
                 it=ssss.find(a[i]);
                if(it!=ssss.end())
                     continue;
                 dfs(i,1);
                ssss.insert(a[i]);
             }
             if(!flag)
                 break;
             len++;
        }
         cout<<endl;
     }
     return 0;
 }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值