您的位置:首页 > 其它

csu D(1973): 给自己出题的小X

2017-07-29 20:17 375 查看

题目:



D(1973): 给自己出题的小X

Submit Page    
Summary    Time
Limit: 1 Sec     Memory
Limit: 128 Mb     Submitted: 38     Solved: 9    


Description

小X学习了dfs,为了练习搜索,开始给自己出题玩。

玩着玩着,一会把自己难住了,一会又被自己难倒了,真是有趣诶!

小X出的题:

现在有N个不同的正整数,求它们可以组成多少个这样的集合,满足:
集合内的元素数量S>1
集合内任意两个数的差的绝对值都大于集合内的元素数量。


Input

第一行,一个正整数T(T<=20)表示数据组数。
对于每组数据,有两行。第一行为一个正整数N(3≤N≤25),第二行为N个用空格隔开的正整数xi(xi≤200)。


Output

对于每组数据,输出一行一个整数表示题中所描述的集合的个数。


Sample Input

1
5
2 3 5 8 1



Sample Output

6



Hint

{5,8},{1,5},{1,8},{2,5},{2,8},{3,8}.
解题思路(复制粘贴版):
可以从第2开始枚举集合里的元素数目,在确定了元素数目之后dfs依次搜索第i个数,dfs过程中保证第i个数合法。
另外,不枚举集合内元素数目也是可以的,直接dfs依次枚举第i个数,当确定下一个数是否合法时,需要检查截止目前的最小相邻间隔是否大于目前集合内的元素数量。这一过程最好在dfs时记录并传递一个相邻间隔最小值。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 100000;
const int maxn = 33;

int a[maxn];
int T,n,m;
ll ans;

void dfs(int num,int pos,int pre,int min_dif)
{
if(num>1&&min_dif>num)
{
ans++;
//printf("num:%d pos:%d pre:%d ans:%d\n",num,pos,pre,ans);
}
if(pos==n)
return;
for(int i=pos;i<n;i++)
{
if(a[i]-pre>num+1)
{
dfs(num+1,i+1,a[i],min(min_dif,a[i]-pre));
}
}
}

int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);

b269
}
ans=0;
sort(a,a+n);
dfs(0,0,-INF,INF);
printf("%lld\n",ans);
}
return 0;
}

/**********************************************************************
Problem: 1973
User: 201601090128
Language: C++
Result: AC
Time:296 ms
Memory:2020 kb
**********************************************************************/


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm