搜索—sequence two
Description
给你一个数字序列,包括 n (<=100) 个整数,每个整数不大于 2^31。你想要找到前 P 个非递减的子序列(如果满足条件的子序列总数 W 小于 P,则只给出前 W 个满足条件的子序列)。子序列的排序规则如下:
首先按子序列的长度进行排序。
其次,按子序列的字典序进行排序。
例如,初始序列 1 3 2 有 5 个满足条件的子序列,按照规则排序如下:
Input
输入包含多个测试用例。
每个测试用例包括,首先是两个整数 n 和 P(其中 1 < n <= 100,1 < p <= 100000)。
Output
对于每个测试用例,按照问题描述输出序列。每个测试用例结束后,跟随一个空行。
Sample Input
3 5
1 3 2
3 6
1 3 2
4 100
1 2 3 2
Sample Output
1
2
3
1 2
1 3
1
2
3
1 2
1 3
1
2
3
1 2
1 3
2 2
2 3
1 2 2
1 2 3
More Info
你必须确保在子序列中的每个子序列都是唯一的。
分析
与2610类似,这个要保留原来的序号,但又有所差别。
代码实现
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
int n,p,len,count_num;
typedef struct
{
int n,pos;
int ind;
}Tem;
Tem tem[1001];
Tem num[1001];
bool cmp(Tem a,Tem b)
{
if(a.n==b.n)
return a.pos<b.pos;
return a.n<b.n;
}
void print_sequence(int length)
{
for(int i = 0; i < length-1;i++)
printf("%d ",tem[i].n);
printf("%d\n",tem[length-1].n);
}
//dep:搜索的深度,也就是目前搜索到子串的长度
//pos: 当前搜索的位置
bool dfs(int dep,int pos,int postion)
{
int pre = 0;
if(dep==len)
{
print_sequence(dep);
count_num++;
if(count_num == p)return 1;
else
return 0;
}
int nowl = 0;
for(int i=pos;i<n;i++)
{
if (num[i].pos >= postion) {
if(nowl == 0){
nowl = 1;
pre = num[i].n;
}
else{
if(num[i].n == pre)
continue;
}
pre=num[i].n;
tem[dep].n = num[i].n;
if(dfs(dep + 1, i + 1,num[i].pos))
return 1;
}
}
return 0;
}
int main()
{
while(scanf("%d%d",&n,&p)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d",&num[i].n);
num[i].pos = i;
}
sort(num,num+n,cmp);
count_num = 0;
for(int i = 1;i < n;i++)
{
//flag=false;
//pre = 0;
len = i;
if(dfs(0,0,0))
break;
}
printf("\n");
}
return 0;
}
//1 2 4 4 5 6 6 8 9

浙公网安备 33010602011771号