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

来源:互联网 发布:淘宝京东商城 编辑:程序博客网 时间:2024/06/05 04:24

题目:

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

        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

152 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]);        }        ans=0;        sort(a,a+n);        dfs(0,0,-INF,INF);        printf("%lld\n",ans);    }    return 0;}/**********************************************************************Problem: 1973User: 201601090128Language: C++Result: ACTime:296 msMemory:2020 kb**********************************************************************/


原创粉丝点击