2174: 小XX的QQ号
Description
一天GJJ去超市购物,一位发传单的小姐姐给了他一张名片;GJJ看到名片上有小姐姐的QQ号,特别激动心想能不能将它分解成两段子序列,完全一样又不互相重叠呢(长度为总长度一半)?
Input
多实例,每次第一行给出一个T,表示T组数据,如果T=0,则表示结束。
接下来每一组数据,第一行一个整数n (2<=n<=30且为偶数)。
第二行输入n个整数;
Output
如果可以输出“竟然还有这种操作”,否则输出“没有这种操作”;输出占一行
Sample Input
2
8
4 2 8 4 9 2 8 9
8
1 2 3 4 5 6 7 8
0
Sample Output
Sample Output
竟然还有这种操作
没有这种操作
Hint
第一个样例可以分解成两个完全一样的子序列 4 2 8 9和4 2 8 9;
题解:
比赛时候上来就开这道题 结果直接跪了快一个小时 下来发现题意都没理解额对啊啊
两个子链应该是 位置在原序列里面不变的 这样就好办了 我们可以跑个DFS
AC代码
#include <bits/stdc++.h>
using namespace std;
#define CLR(a,b) memset(a,(b),sizeof(a))
const int N = 1e3;
int arr[N], brr[N], crr[N];
bool flag;
int n;
void dfs(int pos, int len1, int len2, int st)
{
if(len1>n/2+1 || len2>n/2+1 || flag) return ;
if(len1==n/2+1 && len2==n/2+1) {
flag = true; return ;
}
if(pos == 1) {
brr[1] = arr[1]; dfs(pos+1, len1+1, len2, st);
}
else {
if(arr[pos] == brr[st]) { //说明遇到重复的了 改插到第二个序列里面了
crr[len2] = arr[pos];
dfs(pos+1, len1, len2+1, st+1);
}
brr[len1] = arr[pos];
dfs(pos+1, len1+1, len2, st);
}
}
int main()
{
int T;
while(~scanf("%d",&T),T) {
while(T--) {
scanf("%d",&n);
for(int i = 1; i <= n; i++) scanf("%d",&arr[i]);
flag = false;
dfs(1, 1, 1, 1);
if(flag) puts("竟然还有这种操作");
else puts("没有这种操作");
}
}
return 0;
}

本文介绍了一个有趣的编程问题:检查一个给定的整数序列是否能被拆分成两个完全相同且不重叠的子序列。通过深度优先搜索(DFS)算法解决此问题,并提供了一段AC代码作为解决方案。
1万+

被折叠的 条评论
为什么被折叠?



