题目:
D(1973): 给自己出题的小X
Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 38 Solved: 9Description
小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时记录并传递一个相邻间隔最小值。
另外,不枚举集合内元素数目也是可以的,直接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: 1973
User: 201601090128
Language: C++
Result: AC
Time:296 ms
Memory:2020 kb
**********************************************************************/
#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: 1973
User: 201601090128
Language: C++
Result: AC
Time:296 ms
Memory:2020 kb
**********************************************************************/