欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2017计蒜客第二场(AB)

程序员文章站 2022-05-14 08:20:37
...

A :


百度年会盛况空前,每个部门的年会活动也是非常有趣。某部门的年会中进行了一个有趣的游戏:一张方桌上有四边,每边可以坐一人,每人面前摆放一排长方形木块。我们一次给四边标号,分别为玩家 1、2、3、4(详见下图)。

玩家 1 掷出两个骰子,其点数分别为 x, y(1 \le x, y \le 6)x,y(1x,y6),则从玩家 1 开始按照逆时针(玩家 1、2、3、4)的顺序,数到 x+yx+y 时不妨记为玩家 c,那么从玩家 c 面前顺时针方向第 min(x, y) + 1min(x,y)+1 个木块开始,按照玩家 1、2、3、4 的顺序,每位玩家依次拿走连续的两个木块,循环三次,也就是说每位玩家最终应该有 66 个木块。

注意:按照顺时针方向拿走木块,任何时候(包括拿第一个木块的时候),如果某一边的木块不够拿了,则继续拿顺时针方向下一个玩家的第一个木块。

举个例子,玩家 1 掷骰子点数为 3,53,5,那么应该从玩家 4 顺时针第 44 块木块开始。依次用蓝色、绿色、红色、紫色分别代表玩家 1、2、3、4 拿到的木块,如下图所示:

2017计蒜客第二场(AB)

分别用 num_1, num_2, num_3, num_4num1,num2,num3,num4 表示玩家 1/2/3/41/2/3/4 面前木块的数量。在这些木块中有两个 幸运木块,它们 在同一个玩家面前且相邻。如果 同时拿走这两个幸运木块,就可以拿走年会的终极大奖。

现在轮到 玩家 1 掷骰子,他希望拿走终极大奖,你能帮他算出一共有多少种掷骰子的组合能使得 玩家 1 赢得终极大奖么?不考虑骰子之间的顺序,即 3,43,4 和 4,34,3 被认为是同一种骰子组合。

输入格式

第一行输入 num_1, num_2, num_3, num_4num1,num2,num3,num4 (1 \le num_i < 52,(1numi<52, \sum_{i=1}^4num_i=54)i=14numi=54),依次表示 1/2/3/41/2/3/4 玩家面前摆放的木块数。第二行输入两个整数 k(1 \le k \le 4),k(1k4), d(1 \le d < num_k)d(1d<numk),表示玩家 kk 面前顺时针数第 dd 和 d+1d+1 位置上的木块是幸运木块(从 11 开始计数)。

输出格式

输出一行,表示 玩家 1 能够赢得终极大奖的骰子组合的数目。

样例说明

对于样例,用红色标识出了幸运木块的位置。对应的玩家 1 掷骰子的方案有三种,分别是 (1, 1)(1,1)(1, 5)(1,5)(3, 6)(3,6)

2017计蒜客第二场(AB)

样例输入

10 14 15 15
1 4

样例输出

3


题目大意:


四个人如图,每个人前面有numi快木块,先给出一组筛子的数字组(x,y)然后从第一个玩家开始逆时针数x+y次

停在c然后从c的第min(x,y)+1快木块顺时针开始1,2,3,4依次取两块,循环三次,每个人取6块,总共去24块

现在给你两块相邻的幸运木块位于第k个人前面的第d块和第d+1块,问你玩家1能取得这两块幸运木块的掷筛子

的种类,不考虑顺序


如题.....


题目思路:


因为筛子的范围为1-6,所以考虑枚举所有组合,对于每种组合,我们用两个变量记录当前位于第i个玩家第j个木块

然后循环三次每次j+8,判断i和j是否等于输入的k和d这里需要处理j是否小于numi,然后就是这里是顺时针移动


AC代码:

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int k,d;
    int num[5];    //四个玩家的木块数
    int ans = 0;
    cin>>num[1]>>num[2]>>num[3]>>num[4]>>k>>d;
    for(int i=1;i<6;i++)
    {
        for(int j=i;j<=6;j++)
        {
            int ij = (i+j)%4;      //当前位于第ij个玩家
            if(ij==0)ij = 4;       //余数为0就是4
            int cnt = 3;
            int kk = min(i,j)+1;    //第ij个玩家的第kk的木块
            while(cnt--)
            {
                while(kk>num[ij])      //处理kk>num[ij]的情况
                {
                    kk-=num[ij];
                    ij--;
                    if(ij==0)ij = 4;
                }
                if(ij==k&&kk==d)        //找到答案
                {
                    ans++;
                    break;
                }
                kk+=8;                   //每趟循环kk+8,因为有四个人,每个人取两个
            }
        }
    }
    cout<<ans<<endl;

    return 0;
}


B:

今年,百度的科学计算器进行了重大更新,可以计算更为复杂的表达式了。

定义表达式中存在加减运算、括号、函数调用、强制类型转换这几种运算。其中数值的类型有整型与浮点型两种。并且,

  • 整型与整型加减运算的结果为整型;
  • 整型与浮点型加减运算结果为浮点型;
  • 浮点型与浮点型加减运算结果为浮点型。

强制类型转换符 包括int(x)float(x),其中float(x)运算符可以将数值x的类型强制转为浮点型,int(x)运算符可以将数值x的类型强制转为整型。对于浮点型转整型,采用截尾法,例如:int(1.6)=1int(-1.6)=-1等等。

例如,

  • int(10.9999)=10
  • float(10)=10.000000
  • int(10.9999)+float(1)=11.000000
  • int(1.0)+(100-40)=61

除此以外,还可以定义一系列函数,形如:

  • fun(x,y)=x+y+fun2(y)
  • fun2(x)=fun3()+int(x)
  • fun3()=61

函数的变量名和函数名均由一个或多个大小写字母以及数字组成,并且由大小写字母开头。保证:变量名与函数名不为intfloat;同一函数的不同参数的参数名互不相同;函数名互不相同。函数参数不超过两个,函数之间可能存在相互调用关系,相互调用传参时,各个参数保证均为单一变量(既不是表达式也不是数字常量)。例如f1(x,y)=f2(y,x)+f3(x)+f4()是合法的,而f(x)=f2(x+x)+f3(61)是不合法的(因为函数相互调用时参数不为表达式或数字常量)。

对于给定表达式,百度的科学计算器需要算出该表达式的结果。

输入格式

第一行输入一个整数 n (0 \le n \le 1000)n(0n1000),表示有 nn 个函数。

接下来一共输入 n+1n+1 行,对于前 nn 行,每行一个字符串,分别代表 nn 个函数,每个函数长度均不超过 5050 个字符,字符串中只包含加号+、减号-、括号()、数字常量、强制类型转换以及函数调用。输入数据保证所有表达式合法,表达式中没有空格

最后一行为一个表达式,表示需要求解的表达式,表达式长度不超过 10001000,并且这一表达式中出现函数调用的次数不超过 33 次。

输入数据保证数字常量以及计算过程中数值绝对值均不超过 10^{12}1012,对于浮点型数值常量,保证小数点后不超过 66位。

输入数据保证求解表达式及函数表达式出现的数字常量均为非负数,但计算中间结果不一定非负。

对于简单版本:n=0n=0,在满足题意前提下,求解表达式中不存在强制类型转换int()float()及函数调用;

对于中等版本:n \le 3n3,在满足题意前提下,函数之间不存在相互调用的情况。函数的参数数量均为 11

对于困难版本:满足上述题意中的条件,没有额外的限制。

输出格式

输出为一行,即表达式结果,对于浮点型结果,保留到小数点后 66 位。对于表达式无法求解的情况(例如循环调用),给出No Answer

样例输入1

0
5.0-(4-5.1)

样例输出1

6.100000

样例输入2

3
func1(x)=x+1
func2(y)=y+1
func3(z)=z+int(1.9)
func1(1)+func2(1)+func3(1)

样例输出2

6

样例输入3

2
Haha(x)=Haha1(x)
Haha1(a)=Haha(a)
Haha(61)

样例输出3

No Answer

题目大意:

对于简单版本函数为0,就是计算含有+,-,(),数字的表达式,如果没有浮点数就输出整数否则输出六位浮点数


题目思路:

这个可以用栈或者直接循环求解记录括号的情况或是其他方法都可以,这里是直接循环求解


首先对于数字,我们可以先求出整数部分和小数部分的值(如果有)全部都是double,然后用个op标记-(的个数

op1记录是否有-数字,所以对于每个数如果op%2==0,然后考虑op1,有就是-没有就是+  ,如果op%2==1则相反

然后用个数组记录每个(,如果是+(则存0否则存1,对于每个),数组cnt--,如果出的是1,则op--

这里其实就是记录-的个数,还是看代码吧.....代码有点丑....轻喷.....


AC代码:


#include<bits/stdc++.h>
using namespace std;
char s[100000];
int kh[1000];
int n,len,flag;
int op,op1,cnt;
double ans;
int main()
{
    scanf("%d%s",&n,s);
    len = strlen(s);
    ans = 0,flag = 0;   
    cnt = 0;
    op =op1 = 0;
    for(int i=0;i<len;i++)
    {
        if(s[i]>='0'&&s[i]<='9')
        {
            double x = 0;  //整数部分
            double y =0;    //小数部分
            while(i<len&&s[i]>='0'&&s[i]<='9')
            {
                y = y*10+s[i]-'0';
                i++;
            }
            x+=y;
            y = 0;
            if(s[i]=='.')
            {
                flag = 1;
                i++;
                double xx = 1;
                while(i<len&&s[i]>='0'&&s[i]<='9')
                {
                    y = y*10+s[i]-'0';
                    xx*=10.0;
                    i++;
                }
                i--;
                x+=y/xx;
            }
            else i--;

            if(op%2==0)    //如题解
            {
                if(op1)
                {
                    ans-=x;
                    op1 = 0;
                }
                else ans+=x;

            }
            else
            {
                if(op1)
                {
                    ans+=x;
                    op1 = 0;
                }
                else ans-=x;
            }

        }
        else if(s[i]=='-'||s[i]=='+')
        {
            if(s[i+1]=='(')
            {
                if(s[i]=='-')
                {
                    op++;
                    kh[cnt++]=1;
                }
                else kh[cnt++]=0;
                i++;

            }
            else
            {
                if(s[i]=='-')
                    op1 = 1;
            }
        }
        else if(s[i]==')')
        {
            if(kh[--cnt]==1)op--;
        }
    }
    if(flag)printf("%.6lf\n",ans);
    else printf("%.0lf\n",ans);
    return 0;
}