您的位置:首页 > 其它

【转载】男人八题

2016-12-15 22:39 387 查看
今天看了下男人八题,的确挺难的。看了这篇文章 http://www.cnblogs.com/dramstadt/p/3439725.html
转载如下。不过这个人的表述实在不太清楚。

第一题

题意:n个各不相同的点能组成多少无向连通图?

解:首先要搞清楚,这题必然要用高精度,因为随着n的增长无向连通图的数目的增长将比卡特兰数列更加猛烈.我用的方法是先统计出总共能组成多少无向图,再减去其中不联通的个数.设i个点能组成的无向连通图个数为a[i].n个点之间共有C(n,2)条边可连,总图个数为2^C(n,2).假设图不连通,那么节点1必定在某个连通分量中,由于图不连通,所以节点1所在连通分量节点个数可能为i=1~n-1,则剩下的k=n-i个点可以任意连接,所以a
=Σ(i=1->n-1){a[i]*2^C(k,2)}.想清楚之后关键问题就在于高精度了,借鉴了别人的代码之后,我又花了一下午的时间自己写了一个完全高精度模板,又在VIJOS上刷了十几道高精度题测试,然后再来写这道题,神奇的1A.

#include<stdio.h>
#define gs 30010
int f[gs];
int curf,curt,N;
int abs(int x)
{
if (x<0) return -1*x;
else return x;
}
bool judge(int T)
{
curf=1;
curt=0;
for (int j=1;j<=N;j++)
{
int i=f[j];
if ((i-1)*20<=T) continue;
if (curt+abs(curf-i)*20<=T) continue;
int tr=i-1;
while (true)
{
int tmp=(curt+(curf==1 ? 0:10)+4*(tr+1-curf))+abs(tr+1-i)*20;
if (tmp<=T) tr++;
else break;
}
if (tr==i-1) return false;
curt+=((curf==1 ? 0:10)+4*(tr-curf));
curf=tr;
}
return true;
}
int main()
{
while (scanf("%d",&N)!=EOF)
{
if (N==0) return 0;
for (int i=1;i<=N;i++) scanf("%d",&f[i]);
int l=-1,r=(f
-1)*20,mid;
while (l+1<r)
{
int mid=(l+r)>>1;
if (judge(mid)) r=mid;
else l=mid;
}
printf("%d\n",r);
}
return 0;
}


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