蓝桥杯 算法训练 Glenbow Museum

数据规模和约定
  按题目描述所示。
问题描述
  卡城著名的格林堡博物馆是加拿大西部最大的博物馆,展品涵盖了艺术、文化史以及矿物学。如今一个全新的展区正在被布置,它是专门为你这样杰出的程序猿(媛)打造的。不幸的是,由于空间不足,博物馆打算建造一栋新的建筑来重新安置这个展区。
  新的建筑的尺寸和容量将不同于原始的建筑,但是所有楼层的设计都是直角多边形。一个直角多边形是内角均为90°或270°的多边形。如果我们记90°角为R(Right)、270°角为O(Obtuse),那么一个只包含R和O的字符串能够粗略的表示一个直角多边形。比如,一个矩形(图形1)就是最简单的直角多边形,它能够用RRRR来描述(内角按逆时针排列,起始角任意)。同样地,一个十字形直角多边形(图形2)能够用RRORRORRORRO、RORRORRORROR或者ORRORRORRORR来描述。这些序列被称为角序列。





  当然,一个角序列不一定能完全对应一个形状的多边形,因为它没有说明边长。并且一个角序列不一定能描述一个合法的直角多边形(比如RRROR)。
  为了把事情搞得更麻烦,博物馆并不接受所有的楼层设计。一个博物馆保存了许多价值连城的物品,它们必须要被看守着。出于对成本的考虑,一个楼层最多只能有一个保安。所以只有满足以下要求的楼层设计能被接受:存在一个地点使得一个保安能监视到整个楼层。因此一个角序列能被接受,当且仅当它描述了一个能够被接受的多边形。注意图形2的十字形直角多边形能够被站在中心的保安完全监视,所以它是被接受的,因此角序列RRORRORRORRO是被接受的,即使它也能够描述其他不能被一个保安监视的多边形。
  请帮助新建筑的设计师确定有多少给定长度的能够被接受的角序列。
输入格式
  输入文件包含多组测试数据。每组数据一行,包含一个正整数 L (1 <= L <= 1000),表示给定的角序列长度。
  输入文件以仅包含0的一行结束。
输出格式
  对于每一组数据,输出一行,包含测试数据编号(从1开始),之后为给定长度的被接受的角序列的个数。具体格式参考样例输出。
样例输入
4
6
0
样例输出
Case 1: 1
Case 2: 6



如上图所示:可以的到 R 的数量为r=(n+4)/2 ;O的数量为o=r-4=n-r; 考虑到O不能相邻,则原问题可以转换为一道排列问题,即在数量r个R中插入数量为o的O。由于头和尾同样不能同时为O,则需要分情况讨论:

  1. 开头为R,则sum+= C ( r , o ) =C ( ( n + 4 ) / 2 , 4 )
  2. 开头为O,则sum+= C ( r - 1 , o-1 ) =C ( ( n + 2 ) / 2 , 4) 
#include <iostream>
#include <algorithm>
#include <iomanip>
#define ll long long
using namespace std;
ll C(ll x,ll y){
    if(y<0) return 0;
    ll z=min(y,x-y),ans=1,temp=1;
    for(ll i=x,j=1;j<=z;i--,j++)
        ans*=i,temp*=j;
    return ans/temp;
}
int main() {
    ll n,cnt=1;
    while(cin>>n&&n){
        if(n<4||n%2){
            cout<<"Case "<<cnt++<<": 0"<<endl;
            continue;
        }
        ll r=(n+4)/2,o=n-r;
        cout<<"Case "<<cnt++<<": ";
        cout<<C(r,o)+C(r-1,o-1)<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值