码迷,mamicode.com
首页 > 其他好文 > 详细

LA 4123 Glenbow Museum 葛伦堡博物馆

时间:2015-07-25 00:19:04      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

题意:对于一个边平行于坐标轴的多边形,我们可以用一个由R和O组成的序列来描述它:从某个顶点开始按照逆时针顺序走,碰到一个90°的内角记R;碰到一个270°的内角记O。这样的序列称为角度序列。定义星型多边形为多边形中存在一个点可以看到多边形边界上每一个点。现在给定正整数n,求有多少个长度为L的角度序列至少可以对应一个星型多边形。其中多边形的每条边长任意。









看似很不好下手,有点抽象。实际上我们完全可以假设多边形长度为1,然后构造:

首先,很容易发现多边形顶点数就是n,而且边数也是n。又因为多边形的边都平行于坐标轴,所以L至少为4且必须是偶数。要使多边形为星型多边形,则这个多边形必须存在核。这个题里。多边形的内角只有90°和270°,所以显然可以发现,如果存在两个相邻的内角均为270°,则这个多边形是不存在核的。也就是说,角度序列里不能有两个O相邻,而且头尾也不能同时是O。

然后我们确定R和O的个数。N边形的内角和为(N - 2)*180,而R代表的内角为90,O代表的为270,所以很容易算出R和O的数量,分别为(n + 4)/2个和(n - 4)/2个。于是问题转化为,在n个位置上放置(n - 4)/2个O且任意两个不相邻有多少种放法。

这就是很简单的组合问题了。对于不相邻问题,捆绑法是一种很好的想法。我们将每个O与一个R捆绑起来,并且令R在O的左边。这样捆绑成一个整体,相当于是在n - (n - 4)/2个位置上放置(n - 4)/2个O,也就是放置4个R。答案也就是C((n + 4)/2,4)。注意漏掉一种情况,就是序列开头为O的情况。因为刚才是将R放在O左边。于是我们令第一个为O,那么最后个必须为R,剩下的位置仍然将每个O和R捆绑并且让R在O的左边。这时答案为C((n + 2)/2,4)。所以最后答案就是C((n + 4)/2,4) + C((n + 2)/2,4)。注意别忘了L为奇数或者小于4的情况特判输出0。







#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<iomanip>
#include<string>
using namespace std;

long long L;

int main()
{
    int Case = 0;
    while(scanf("%lld", &L) && L)
    {
        printf("Case %d: ", ++Case);
        if(L&1 || L < 4)
        {
            printf("0\n");
            continue;
        }
        long long ans1 = (L + 4) >> 1, ans2 = (L + 2) >> 1;
        ans1 = ans1*(ans1 - 1)*(ans1 - 2)*(ans1 - 3)/24;
        ans2 = ans2*(ans2 - 1)*(ans2 - 2)*(ans2 - 3)/24;
        printf("%lld\n", ans1 + ans2);
    }
    return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

LA 4123 Glenbow Museum 葛伦堡博物馆

标签:

原文地址:http://blog.csdn.net/firstlucker/article/details/47048405

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!