【noip2008普及】传球游戏

来源:互联网 发布:三菱plc编程软件work2 编辑:程序博客网 时间:2024/05/25 08:15

题目描述

上体育课的时候,小蛮的老师经常带着同学们一起做游戏。这次,老师带着同学们一起做传球游戏。

游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时,拿着球没有传出去的那个同学就是败者,要给大家表演一个节目。

聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了m次以后,又回到小蛮手里。两种传球方法被视作不同的方法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有三个同学1号、2号、3号,并假设小蛮为1号,球传了3次回到小蛮手里的方式有1->2->3->1和1->3->2->1,共2种。

输入输出格式

输入格式:
输入文件ball.in共一行,有两个用空格隔开的整数n,m(3<=n<=30,1<=m<=30)。

输出格式:
输出文件ball.out共一行,有一个整数,表示符合题意的方法数。

输入输出样例

输入样例#1: 复制
3 3
输出样例#1: 复制
2
说明

40%的数据满足:3<=n<=30,1<=m<=20

100%的数据满足:3<=n<=30,1<=m<=30

2008普及组第三题

#include<cstdio>#include<algorithm>using namespace std;const int mod=10007;int n,zhan0[50000],zhan1[50000],top0,top1,topop=0;char ch[100000],op[50000];inline int read(){    int now=0,f=1; char ch=getchar();    while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}    while (ch>='0'&&ch<='9')    {        now=(now<<1)+(now<<3)+ch-'0';        ch=getchar();    }    return now*f;}void write(int x){    if (x<0) {putchar('-'); x=-x;}    if (x>=10) write(x/10);    putchar(x%10+'0');}int level(char ch){    switch (ch)    {        case '+':return 1; break;        case '*':return 2; break;        case '(':return 0; break;    }}void calc(char ch){    switch (ch)    {        case '+':            {                int sh0=zhan0[top0]%mod*zhan0[top0-1]%mod;//乘号写成了加号                 int sh1=zhan0[top0-1]%mod*zhan1[top1]%mod+zhan1[top1-1]%mod*zhan0[top0]%mod+zhan1[top1-1]%mod*zhan1[top1]%mod;                zhan0[--top0]=sh0%mod; zhan1[--top1]=sh1%mod;                break;            }        case '*':            {                int sh1=zhan1[top1]%mod*zhan1[top1-1]%mod;                int sh0=zhan0[top0-1]%mod*zhan1[top1]%mod+zhan1[top1-1]%mod*zhan0[top0]%mod+zhan0[top0-1]%mod*zhan0[top0]%mod;                zhan0[--top0]=sh0%mod; zhan1[--top1]=sh1%mod;                break;            }    }}void push_num()//加入数字1 {    zhan0[++top0]=1; zhan1[++top1]=1;}int main(){    n=read();    for (int i=1; i<=n; i++)        scanf("%c",&ch[i]);    ch[0]='('; ch[++n]=')';    int i=0;    while (i<=n)    {        if (ch[i]==' ') {i++; continue;}        else if (ch[i]=='(') {op[++topop]='('; if (ch[i+1]!='(') push_num();}//括号左边放一个,右边放一个         else if (ch[i]==')'){            if (op[topop]=='(') topop--;            while (op[topop]!='(') calc(op[topop--]);            topop--;//减去左括号         }        else if (level(op[topop])>=level(ch[i]))//忘记了level,一定要细心!        {            while (level(op[topop])>=level(ch[i])) calc(op[topop--]);            op[++topop]=ch[i];            push_num();        }        else if (level(op[topop])<level(ch[i]))        {            op[++topop]=ch[i];            if (ch[i+1]!='(') push_num();        }        i++;    }    write(zhan0[1]%mod);    return 0;}