第十四届蓝桥杯三月真题刷题训练——第 21 天

第 1 题:灭鼠先锋

问题描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

灭鼠先锋是一个老少咸宜的棋盘小游戏,由两人参与,轮流操作。

灭鼠先锋的棋盘有各种规格,本题中游戏在两行四列的棋盘上进行。游戏的规则为:两人轮流操作,每次可选择在棋盘的一个空位上放置一个棋子,或在同一行的连续两个空位上各放置一个棋子,放下棋子后使棋盘放满的一方输掉游戏。

小蓝和小乔一起玩游戏,小蓝先手,小乔后手。小蓝可以放置棋子的方法很多,通过旋转和翻转可以对应如下四种情况:

XOOO XXOO OXOO OXXO
OOOO OOOO OOOO OOOO

其中 O 表示棋盘上的一个方格为空,X 表示该方格已经放置了棋子。

请问,对于以上四种情况,如果小蓝和小乔都是按照对自己最优的策略来玩游戏,小蓝是否能获胜。如果获胜,请用 V 表示,否则用 L 表示。请将四种情况的胜负结果按顺序连接在一起提交。

思路:谁先把第一排放满谁就赢了

#include <bits/stdc++.h>
using namespace std;
int main()
{
  cout<<"LLLV"<<endl;
}
第 2 题:小蓝与钥匙
问题描述
小蓝是幼儿园的老师, 他的班上有 28 个孩子, 今天他和孩子们一起进行了 一个游戏。
小蓝所在的学校是寄宿制学校, 28 个孩子分别有一个自己的房间, 每个房 间对应一把钥匙, 每把钥匙只能打开自己的门。现在小蓝让这 28 个孩子分别将 自己宿舍的钥匙上交, 再把这 28 把钥匙随机打乱分给每个孩子一把钥匙, 有28!=28×27×⋯×1 种分配方案。小蓝想知道这些方案中, 有多少种方案恰有 一半的孩子被分到自己房间的钥匙 (即有 14 个孩子分到的是自己房间的钥匙, 有 14 个孩子分到的不是自己房间的钥匙)。

思路:首先固定住一半的人的位置正确,剩下一半的人错排;固定住一半的人数量为C(28,14)

注意不要先求28的阶乘再除以14的阶乘,数据太大会爆范围

【组合数学】错排问题 ( 递推公式 | 通项公式 | 推导过程 ) ★_错排问题递推公式_韩曙亮的博客-优快云博客
#include <iostream>
#define ll long long
using namespace std;
ll D[15];
int main() {
    ll ans=1,cnt=1,res;
    for(int i=1; i<=14; i++) {
        cnt=cnt*(28-i+1)/i;
    }
    D[0] = D[1] = 0;
    D[2] = 1;
    for (int i = 3; i <= 14; i++) {
        D[i] = (i - 1) * (D[i - 1] + D[i - 2]);
    }
    cout<<cnt*D[14]; 
}
第 3 题:李白打酒加强版 题解链接:题解
问题描述
话说大诗人李白, 一生好饮。幸好他从不开车。
一天, 他提着酒显, 从家里出来, 酒显中有酒 2 斗。他边走边唱:
无事街上走,提显去打酒。 逢店加一倍, 遇花喝一斗。
这一路上, 他一共遇到店 N 次, 遇到花 M 次。已知最后一次遇到的是花, 他正好把酒喝光了。
请你计算李白这一路遇到店和花的顺序, 有多少种不同的可能?
注意: 显里没酒 ( 0 斗) 时遇店是合法的, 加倍后还是没酒; 但是没酒时遇 花是不合法的。
输入格式
第一行包含两个整数 NM.
输出格式
输出一个整数表示答案。由于答案可能很大,输出模 1000000007 的结果.

思路:动态规划

状态转移方程:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=110;
ll f[N][N][N];//存放每一种状态的数量
ll n,m,mod=1000000007;
int main() {
    cin>>n>>m;
    f[0][0][2]=1;//初始状态
    ll ans=0,k=0;
    for(int i=0; i<=n; i++) { //店
        for(int j=0; j<=m; j++) {//花的数量
            for(int k=0; k<=m; k++) { //酒的数量不大于花的数量 ,否则无法减完
                if(i>0&&k%2==0)//遇店,因为此时是偶数的话,那么前一个状态一定是遇店 
                    f[i][j][k]=(f[i][j][k]+f[i-1][j][k/2])%mod;
                if(j>0)//遇花
                    f[i][j][k]=(f[i][j][k]+f[i][j-1][k+1])%mod;
            }
        }
    }
    cout<<f[n][m-1][1];//确保最后一次是花 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值