练习赛
一、题目概览
|
中文题目名称 |
树 |
红与蓝 |
猜数列 |
|
英文题目名称 |
tree |
rab |
hidden |
|
可执行文件名 |
tree |
rab |
hidden |
|
输入文件名 |
tree.in |
rab.in |
hidden.in |
|
输出文件名 |
tree.out |
rab.out |
hidden.out |
|
时间限制 |
1s |
1s |
1s |
|
空间限制 |
256MB |
256MB |
256MB |
|
测试点数目 |
10 |
10 |
25 |
|
测试点分值 |
10 |
10 |
4 |
|
题目类型 |
传统 |
传统 |
传统 |
|
比较方式 |
全文比较 |
spj |
全文比较 |
|
是否有部分分 |
否 |
是 |
否 |
二、注意事项:
1.文件名(程序名和输入输出文件名)必须使用小写。
2.C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。
3.开启O2优化,栈空间开大至256M。
树(tree)
【题目描述】
有n个点,第i个点的限制为度数不能超过ai。
现在对于每一个s(1<=s<=n),问从这n个点中选出s个点组成有标号无根树的方案数。
【输入数据】
第一行一个整数表示n。
第二行n个整数a1~an。
【输出数据】
一个n个整数,第i个整数表示s=i时的答案。
答案模1004535809
【样例输入】
3
2 2 1
【样例输出】
3 3 2
【数据范围】
对于20%的数据,n≤6。
对于60%的数据,n≤50。
对于100%的数据,n≤100。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define maxn 101 #define mod 1004535809 using namespace std; int n,a[maxn],ans[maxn],t[maxn],num,b[maxn]; bool vis[maxn]; void dfs2(int pos){ if(pos==num-1){ ans[num]++; if(ans[num]>=mod)ans[num]-=mod; return; } for(int i=1;i<=num;i++){ int ii=b[i]; if(t[ii]!=a[ii]-1){ t[ii]++; dfs2(pos+1); t[ii]--; } } } void dfs1(int pos,int id){ if(pos==n+1){ return; } for(int i=id;i<=n;i++){ if(!vis[i]){ b[pos]=i; vis[i]=1; if(pos>=3)num=pos,dfs2(1); dfs1(pos+1,i+1); vis[i]=0; } } } int main(){ // freopen("Cola.txt","r",stdin); freopen("tree.in","r",stdin);freopen("tree.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); sort(a+1,a+n+1); for(int i=n;i>=1;i--){ if(a[i]>n-1)a[i]=n-1; else break; } ans[1]=n;ans[2]=(n-1)*n/2; dfs1(1,1); for(int i=1;i<=n;i++)printf("%d ",ans[i]); return 0; }