第 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 斗) 时遇店是合法的, 加倍后还是没酒; 但是没酒时遇 花是不合法的。
输入格式
第一行包含两个整数 N 和 M.
输出格式
输出一个整数表示答案。由于答案可能很大,输出模 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];//确保最后一次是花
}