zoukankan      html  css  js  c++  java
  • UVA 11971 Polygon

    https://vjudge.net/problem/UVA-11971

    题目

    有一根长度为$n$的木条,随机选$k$个位置把他们切成$k+1$段木条,求这些小木条能组成一个多边形的概率。

    题解

    能组成多边形可以转化为最长的木条长度小于剩余木条长度的和。

    先证明任意的$n$边形都能通过合并两条边转化为一个$(n-1)$边形

    如图,AE,DE可以构成AF,DC=CF,就可以减少一条边,一直减少,就可以得到一个三角形,反过来,三角形也可以拆成多边形

    如果每次都选择最长的边,那么最后就能得到一个三角形。根据三角形组成的充要条件,就可以得到整个多边形最长的边小于其他边之和。

    于是问题就变成了一个线段上面随机切$K$次,求最长的线段长度大于等于$frac{1}{2}$的概率。

    那么只算在线段的1/2长度外面切

    下面用了一个构造,先把线段拼成一个圆,然后只在圆的一半部分切,然后选一个端点拆成线段

    概率就是$1-frac{1}{2}^K imes (k+1)$(此处存疑= =)

    AC代码

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define REP(i,a,b) for(register int i=(a); i<(b); i++)
    #define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
    #define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
    #ifdef sahdsg
    #define DBG(...) printf(__VA_ARGS__)
    #else
    #define DBG(...) (void)0
    #endif
    #define ln log
    using namespace std;
    typedef long long LL;
    int n,k;
    LL gcd(LL a, LL b) {
    	return b==0?a:gcd(b,a%b);
    }
    int main() {
    	int T; scanf("%d", &T);
    	int kase=0;
    	while(0<T--) {
    		scanf("%d%d", &n, &k);
    		//(2^k-1+k)/(2^k)
    		LL a=(1ULL<<k)-1-k;
    		LL b=1ULL<<k;
    		LL g=gcd(a,b);
    		a/=g, b/=g;
    		printf("Case #%d: %lld/%lld
    ", ++kase, a, b);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Django中的syncdb命令
    notepad++下的字体设置
    python中的getattr函数
    python实现虚拟茶话会
    利用python爬取海量疾病名称百度搜索词条目数的爬虫实现
    SQL里面如何取得前N条数据?
    python中怎么查看当前工作目录和更改工作目录
    python中thread模块中join函数
    python中的自测语句是什么?
    python读取数据库数据有乱码怎么解决?
  • 原文地址:https://www.cnblogs.com/sahdsg/p/11806583.html
Copyright © 2011-2022 走看看