1.题目编号:1024
2.简单题意:给定若干序列,每一个序列要找出一定数目的子序列,会给你一个p值,是输出子序列的个数,输出的子序列可以小于p,即当子序列的全部个数小于p,就只把全部序列输出即可。子序列需要满足个数递增,而且前面的数不能大于后面的数
3.解题思路形成过程:本专题讲的是广度搜索和深度搜索,一开始就想到需要用深度搜索。但在搜索时需要注意,当发现两个的子序列都不存在,那么比它长的子序列更没有了,在这个时候就可以全部输出了。另外,在深度搜索中需要判断两次,首先,如果搜索的是子序列的第一个元素,那么需要判断在原始序列的开始到当前位置有没有出现过该元素,如果出现过则证明已经搜索过了,然后,判断子序列中不是第一个元素的元素,需要判断该元素的前一个元素在原始序列的位置,从原始序列位置的下一个元素开始到元素的位置,有没有出现过和该元素相同的元素,如果有,继续搜索就会重复。例如8 100 1 2 3 4 5 2 6 3,搜索第二个2作为子序列的第一个元素时,就运用了第一个判断,当第二个2作为子序列第2元素时,运用了第二种判断。
4.感想:在A题的时候,一开始出现输入格式错误,原来在输出子序列的时候最后一个元素后面没有空格,直接回车,细节好重要。深度搜索和广度搜索的题真的好难,根本就想不到那么深,有时候读完题一点思路都没有,可能广度搜索和深度搜索自己还没有理解,继续加油吧~
5.AC的代码:
#include <iostream>
#include <algorithm>
using namespace std;
int n,p,len,count_num;
int num[1001];
bool flag;
struct Tem
{
int n,pos;
};
Tem tem[1001];
bool check(int s,int e)
{
for(int i = s+1; i < e; i++)
if(num[i]==num[e])
return false;
return true;
}
void print_sequence(int length)
{
for(int i = 0; i < length-1;i++)
cout<<tem[i].n<<" ";
cout<<tem[length-1].n<<endl;
}
void dfs(int dep,int pos)
{
if(count_num >= p)return;
if(dep==len)
{
count_num++;
flag = true;
print_sequence(len);
return;
}
for(int i=pos;i<n;i++)
{
if((dep!=0&&tem[dep-1].n<=num[i])||dep==0)
{
if(dep==0&&!check(-1,i))
continue;
if(dep!=0&&!check(tem[dep-1].pos,i))
continue;
tem[dep].n = num[i];
tem[dep].pos = i;
dfs(dep+1,i+1);
}
}
return;
}
int main()
{
while(cin>>n>>p)
{
for(int i=0;i<n;i++)
cin>>num[i];
count_num = 0;
for(int i = 1;i < n;i++)
{
flag=false;
len = i;
dfs(0,0);
if(count_num>=p||!flag)break;
}
cout<<endl;
}
return 0;
}
原题:
3 5<br>1 3 2<br>3 6<br>1 3 2<br>4 100<br>1 2 3 2<br>
1<br>3<br>2<br>1 3<br>1 2<br><br>1<br>3<br>2<br>1 3<br>1 2<br><br>1<br>2<br>3<br>1 2<br>1 3<br>2 3<br>2 2<br>1 2 3<br>1 2 2<br><