SMU 2026 Spring 天梯赛5题解
7-3 冠军魔术
题意:
给定初始纸牌数量 \(a\) 和推送次数 \(n\)。每次推送:纸牌变硬币数量不变,硬币变纸牌数量加倍。初始为纸牌。求 \(n\) 次后是纸牌还是硬币,以及数量。
思路:
推送奇数次后为硬币,偶数次后为纸牌。数量每次从硬币变纸牌时加倍,总共加倍次数为 \(n/2\) 次。因此数量为 \(a \times 2^{n/2}\)。
代码
点击查看代码
void solve() {
int x,y;
cin>>x>>y;
int p=0;
while(p<y){
p++;
if(p%2==0){
x*=2;
}
}
cout<<y%2<<' '<<x<<endl;
}
7-4 Cassels方程
题意:
判断给定的三个正整数 \(x\), \(y\), \(z\) 是否满足方程 \(x^2 + y^2 + z^2 = 3 \cdot x \cdot y \cdot z\)。
思路:
直接计算等式左右两边的值,比较是否相等即可。注意数据范围在 1000 以内,但乘积可能较大,使用 long long 避免溢出。
代码
点击查看代码
void solve() {
int x,y,z;
cin>>x>>y>>z;
if(x*x+y*y+z*z==3*x*y*z){
cout<<"Yes\n";;
}else{
cout<<"No\n";
}
}
7-5 吉老师的回归
题意:
给定 N 个题目描述字符串,吉老师按顺序看题,但跳过包含“qiandao”或“easy”(区分大小写)的题目。已知吉老师做完了 M 道题目(实际做的,不包括跳过的),求他当前正在做的题目。如果已做完所有有效题目,输出“Wo AK le”。
思路:
模拟吉老师的做题过程。遍历每个题目,检查是否包含关键词,若包含则跳过。维护一个计数器 cnt 表示有效题目数。当 cnt 等于 M 时,记录下一个有效题目作为答案。遍历结束后,若未记录到答案,则输出“Wo AK le”。
代码
点击查看代码
int n,m;
cin>>n>>m;
string s,t="Wo AK le";
getline(cin,s);
int p=0;
for(int i=1;i<=n;i++){
getline(cin,s);
if(s.find("qiandao")!=-1||s.find("easy")!=-1){
continue;
}
if(p==m){
t=s;
}
p++;
}
cout<<t<<endl;
}
7-6 大笨钟的心情
题意:
给定 24 个整数,代表一天 24 小时的心情指数。随后输入若干询问,每个询问是一个小时数(0-23),要求输出该小时的心情指数以及是否大于 50(大于则输出 Yes,否则输出 No)。当输入非法小时数(不在 0-23 范围内)时结束输入。
思路:
直接用数组存储 24 个心情指数,对于每个合法询问,输出对应位置的值并判断是否大于 50 即可。
代码
点击查看代码
void solve() {
for(int i=0;i<24;i++){
cin>>a[i];
}
int x;
while(cin>>x){
if(x==-1)break;
if(x<0||x>23)continue;
cout<<a[x]<<' ';
if(a[x]>50){
cout<<"Yes\n";
}else{
cout<<"No\n";
}
}
}
7-7 爆气球
题意:
给定 \(n\) 个递增的整数坐标和一个长度 \(h\)。孩子跳到一个位置 \(x\),躺平后身体覆盖区间 \([x, x+h]\)。求一个位置 \(x\),使得区间覆盖的气球数最多,输出 \(x\) 和覆盖数。如果有多个 \(x\),输出最小的 \(x\)。
思路:
由于坐标有序,使用双指针维护一个滑动窗口,窗口内点的最大差不超过 \(h\)。对于每个窗口,覆盖数为窗口点数,对应的最小 \(x\) 为窗口最大坐标减去 \(h\)。遍历所有窗口,记录最大覆盖数和对应的最小 \(x\)。
代码
点击查看代码
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
//#define int long long
#define ll long long
const int mod = 998244353;
#define PII pair<int,int>
#define MAXN 100010
#define EXP 20//32
const int INF = 0x3f3f3f3f;
void solve() {
int n, h;
cin >> n >> h;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
int mx = 0, ans = 0;
int j = 0;
for (int i = 0; i < n; i++) {
while (j < n && a[j] - a[i] <= h) j++;
int cnt = j - i;
if (cnt > mx) {
mx = cnt;
ans = a[j - 1] - h;
} else if (cnt == mx) {
ans = min(ans, a[j - 1] - h);
}
}
cout << ans << " " << mx << endl;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
}
7-8 帅到没朋友
题意:
给定 N 个朋友圈,每个朋友圈有 K 个人(K=1 表示只有自己)。如果一个人出现在某个 K>1 的朋友圈中,则他有朋友。接下来有 M 个查询,按顺序输出那些没有朋友的人(同一个人只输出一次)。如果没有,输出 "No one is handsome"。
思路:
用数组标记出现在 K>1 朋友圈中的人(有朋友)。查询时,按顺序检查是否被标记过,并且只输出第一次出现的无朋友者。注意输出 ID 为 5 位数字(前补零)。
代码
点击查看代码
int a[N];
int fa[N];
int find(int x){
if(find(x)==fa[x])return fa[x];
fa[x]=find(x);
return fa[x];
}
string ff(int x){
string s=to_string(x);
while(s.length()<5)s='0'+s;
return s;
}
void solve() {
int n,h;
cin>>n;
for(int i=0;i<1e6;i++){
fa[i]=i;
}
for(int i=1;i<=n;i++){
int k;
cin>>k;
int ls;
for(int j=1;j<=k;j++){
int x;
cin>>x;
if(k>1){
a[x]=1;
}
}
}
int m;
cin>>m;
int f=1;
for(int i=1;i<=m;i++){
int x;
cin>>x;
if(a[x]==0){
if(f){
f=0;
}else{
cout<<' ';
}
cout<<ff(x);
a[x]=1;
}
}
if(f){
cout<<"No one is handsome";
}
}
7-9 海盗分赃
题意:
P个海盗偷了D颗钻石,按抽签顺序1到P编号。由1号开始提出分配方案(给出每个海盗具体分到的钻石数),如果得到绝对多数(大于半数)同意,则执行;否则1号被杀死,由2号继续提出方案,直到方案通过或只剩最后一个海盗独占所有钻石。海盗行为准则:
- 以自身利益最大化为准;
- 在利益相同时,不会故意致同伙于死地(即不会在利益相同时选择杀人);
- 分配钻石时,优先分给序号小的海盗。
给定D和P(3≤P≤D≤100),求1号海盗在自己提出的方案中最多能获得多少钻石。
本题为经典博弈论题目,有兴趣的自行搜索了解。
思路:
逆推法。从最后只剩一个海盗(P号)开始,逐步增加海盗数,计算每个海盗作为提议者时,为让方案通过所需的最小花费(给其他海盗的钻石),从而最大化自身所得。
对于当前提议者i(总人数n = P-i+1),需获得至少need = n/2+1人同意(包括自己)。他从i+1到P号海盗中选择need-1人,用钻石收买。对于海盗j,若当前轮给他x颗钻石,他同意的条件是x > next[j](其中next[j]为下一轮中j能获得的钻石数)。
提议者i会优先选择next[j]最小的海盗,给这些海盗next[j]+1颗钻石以争取同意。计算总花费sum,若sum ≤ D则方案可行,i获得D - sum颗钻石,并更新next数组(被收买的海盗j的next值变为next[j]+1,其余为0);若不可行则i获得0颗且next数组不变(i被杀)。最终next[1]即为答案。
代码
点击查看代码
void solve() {
int D,P;
cin>>D>>P;
vector<int>q;
q.push_back(D);
q.push_back(0);
for(int i=3;i<=P;i++){
sort(q.begin(),q.end());
int x=i/2;
int s=D;
for(int j=0;j<x;j++){
q[j]=min(s,q[j]+1);
s-=q[j];
}
for(int j=x;j<q.size();j++){
q[j]=0;
}
q.push_back(s);
// for(int j=0;j<i;j++){
// cout<<q[j]<<" \n"[j==i-1];
// }
}
cout<<q.back()<<endl;
}
7-10取行李
题意:
给定一个正整数 \(N\) 和一个 \(1\) 到 \(N\) 的重排列,表示旅客的排队顺序。行李按顺序 \(1\) 到 \(N\) 到达传送带窗口,行李 \(i\) 属于旅客 \(i\)。每个人到窗口时,如果行李不是自己的,就走到队尾等待,行李留在窗口。每次检查需要 \(1\) 分钟。求所有行李被取走的总时间和旅客的平均等待时间(从开始到行李被取走的时间)。
思路:
模拟过程。维护一个旅客队列,对于每个行李 \(i\),从队首开始检查,如果不匹配则队首移到队尾,时间加 \(1\);直到匹配,时间加 \(1\) 并取走行李,累加等待时间。总时间即为最后取走行李的时间,平均等待时间为总等待时间除以 \(N\)。
代码
点击查看代码
void solve() {
int n;
cin>>n;
queue<int>q;
for(int i=1;i<=n;i++){
int x;
cin>>x;
q.push(x);
}
int s=0,ans=0;
for(int i=1;i<=n;i++){
int s1=0;
while(q.front()!=i){
s1++;
q.push(q.front());
q.pop();
}
q.pop();
s1++;
s+=s1*(n+1-i);
ans+=s1;
}
cout<<fixed<<setprecision(1)<<ans<<' '<<s*1.0/n<<endl;
}
7-11 德才论
题意:
给定 \(n\) 个考生的准考证号、德分和才分,以及最低分数线 \(l\) 和优先录取线 \(h\)。首先筛选出德分和才分均不低于 \(l\) 的考生,然后根据以下规则分为四类:
- 第一类:德分和才分均不低于 \(h\)。
- 第二类:德分不低于 \(h\),但才分低于 \(h\)(不低于 \(l\))。
- 第三类:德分和才分均低于 \(h\),但德分不低于才分。
- 其他:剩余达到 \(l\) 的考生。
对每类考生分别按总分降序排序,若总分相同则按德分降序排序,若德分也相同则按准考证号升序排序。输出达标考生总数,并按类别顺序(1→2→3→4)输出所有考生信息。
思路:
直接模拟分类过程,使用四个 vector 分别存储四类考生。读入时根据条件将考生放入对应的容器,然后对每个容器按题目要求排序。最后输出总人数并按顺序输出所有考生。
代码
点击查看代码
struct asd{
string id;
int s1,s2;
};
bool cmp(asd x,asd y){
if(x.s1+x.s2!=y.s1+y.s2)return x.s1+x.s2>y.s1+y.s2;
if(x.s1!=y.s1)return x.s1>y.s1;
return x.id<y.id;
}
void solve() {
int n,l,h;
cin>>n>>l>>h;
vector<asd>q1,q2,q3,q4;
for(int i=1;i<=n;i++){
asd x;
cin>>x.id>>x.s1>>x.s2;
if(x.s1>=h&&x.s2>=h){
q1.push_back(x);
}else if(x.s1>=h&&x.s2>=l){
q2.push_back(x);
}else if(x.s1>=l&&x.s2>=l&&x.s1>=x.s2){
q3.push_back(x);
}else if(x.s1>=l&&x.s2>=l){
q4.push_back(x);
}
}
sort(q1.begin(),q1.end(),cmp);
sort(q2.begin(),q2.end(),cmp);
sort(q3.begin(),q3.end(),cmp);
sort(q4.begin(),q4.end(),cmp);
cout<<q1.size()+q2.size()+q3.size()+q4.size()<<endl;
for(int i=0;i<q1.size();i++){
cout<<q1[i].id<<' '<<q1[i].s1<<' '<<q1[i].s2<<endl;
}
for(int i=0;i<q2.size();i++){
cout<<q2[i].id<<' '<<q2[i].s1<<' '<<q2[i].s2<<endl;
}
for(int i=0;i<q3.size();i++){
cout<<q3[i].id<<' '<<q3[i].s1<<' '<<q3[i].s2<<endl;
}
for(int i=0;i<q4.size();i++){
cout<<q4[i].id<<' '<<q4[i].s1<<' '<<q4[i].s2<<endl;
}
}
7-12 红色警报
题意:
给定一个包含 N 个城市和 M 条道路的图,需要按顺序处理 K 个城市被攻占的事件。每次攻占一个城市后,需要判断国家的连通性是否发生变化(即连通分量数量是否增加)。如果增加,发出红色警报;否则只输出普通信息。如果所有城市都被攻占,最后输出"Game Over."。
思路:
使用并查集的思想模拟删除城市后的连通分量数量。每次删除城市后,重新计算剩余城市的连通分量数量,并与之前进行比较。
代码
点击查看代码
vector<int>g[N];
int vis[N];
int vv[N];
int a[N],b[N];
int dfs(int x){
vis[x]=1;
int s=vis[x]-vv[x];
for(auto u:g[x]){
if(!vis[u]){
s+=dfs(u);
}
}
return s;
}
void solve() {
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
int s=0;
for(int i=0;i<n;i++){
if(!vis[i]){
a[i]=dfs(i);
s++;
}
}
int k;
cin>>k;
for(int l=1;l<=k;l++){
int x;
cin>>x;
vv[x]=1;
for(int i=0;i<n;i++){
vis[i]=vv[i];
b[i]=0;
}
int f=1;
int ss=0;
for(int i=0;i<n;i++){
if(!vis[i]){
b[i]=dfs(i);
ss++;
}
a[i]=b[i];
}
if(s<ss){
f=0;
}
s=ss;
if(f){
cout<<"City "<<x<<" is lost.\n";
}else{
cout<<"Red Alert: City "<<x<<" is lost!\n";
}
}
int f=0;
for(int i=0;i<n;i++){
if(!vv[i]){
f=1;
}
}
if(!f){
cout<<"Game Over.\n";
}
}
7-13 森森美图
题意:
给定一个 \(N \times M\) 的网格,每个格子有一个分值。给定起点 \(A(sx, sy)\) 和终点 \(B(tx, ty)\)。连接 \(A\) 和 \(B\) 的直线将网格分为两部分(不包括直线上的点)。需要在每一部分中分别找一条从 \(A\) 到 \(B\) 的八连通路径,使得两条路径的总得分最小。得分计算规则:
- 若从 \((x,y)\) 走到正交相邻格(上下左右),得分增加目标格的分值。
- 若走到斜向相邻格,得分增加目标格分值 \(+\) (当前格分值 \(+\) 目标格分值)\(\times (\sqrt{2}-1)\)。
起点和终点的分值只计算一次(即总得分要减去一次起点和一次终点的分值)。
思路:
使用 Dijkstra 算法求最短路径。分别对直线的两侧进行两次最短路计算,每次只允许访问该侧的点(但允许最后一步走到终点)。判断点 \(P\) 位于直线的哪一侧使用叉积:\(\overrightarrow{AB} \times \overrightarrow{AP}\) 的符号。注意坐标原点在左上角,\(y\) 轴向下为正,叉积公式为 \((tx-sx)*(Y-sy) - (ty-sy)*(X-sx)\)。
代码
点击查看代码
int a[N][N];
double mn[N][N];
int vis[N][N];
int xx[4] = {1, 0, -1, 0};
int yy[4] = {0, 1, 0, -1};
int xxx[4] = {1, 1, -1, -1};
int yyy[4] = {-1, 1, -1, 1};
void solve() {
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> a[j][i];
mn[j][i] = 1e18;
}
}
int sx, sy, tx, ty;
cin >> sx >> sy >> tx >> ty;
priority_queue<PIII, vector<PIII>, greater<PIII>>q;
q.push({a[sx][sy], {sx, sy}});
mn[sx][sy] = a[sx][sy];
while (q.size()) {
auto [s, u] = q.top();
q.pop();
auto [x, y] = u;
if (vis[x][y]) {
continue;
}
vis[x][y] = 1;
for (int i = 0; i < 4; i++) {
int X = x + xx[i];
int Y = y + yy[i];
if (X < 0 || X >= m || Y < 0 || Y >= n)continue;
if ((ty - sy) * (X - sx) <= (tx - sx) * (Y - sy)) {
if (X == tx && Y == ty && (x != sx || y != sy)) {
double ss = s + a[X][Y];
if (ss < mn[X][Y]) {
mn[X][Y] = ss;
}
}
continue;
}
double ss = s + a[X][Y];
if (ss < mn[X][Y]) {
mn[X][Y] = ss;
q.push({ss, {X, Y}});
}
}
for (int i = 0; i < 4; i++) {
int X = x + xxx[i];
int Y = y + yyy[i];
if (X < 0 || X >= m || Y < 0 || Y >= n)continue;
if ((ty - sy) * (X - sx) <= (tx - sx) * (Y - sy)) {
if (X == tx && Y == ty && (x != sx || y != sy)) {
double ss = s + a[X][Y] + (a[x][y] + a[X][Y]) * (sqrtl(2) - 1);
if (ss < mn[X][Y]) {
mn[X][Y] = ss;
}
}
continue;
}
double ss = s + a[X][Y] + (a[x][y] + a[X][Y]) * (sqrtl(2) - 1);
if (ss < mn[X][Y]) {
mn[X][Y] = ss;
q.push({ss, {X, Y}});
}
}
}
double s1 = mn[tx][ty];
mn[tx][ty] = 1e18;
q.push({a[sx][sy], {sx, sy}});
vis[sx][sy] = 0;
while (q.size()) {
auto [s, u] = q.top();
q.pop();
auto [x, y] = u;
if (vis[x][y]) {
continue;
}
vis[x][y] = 1;
for (int i = 0; i < 4; i++) {
int X = x + xx[i];
int Y = y + yy[i];
if (X < 0 || X >= m || Y < 0 || Y >= n)continue;
if ((ty - sy) * (X - sx) >= (tx - sx) * (Y - sy)) {
if (X == tx && Y == ty && (x != sx || y != sy)) {
double ss = s + a[X][Y];
if (ss < mn[X][Y]) {
mn[X][Y] = ss;
}
}
continue;
}
double ss = s + a[X][Y];
if (ss < mn[X][Y]) {
mn[X][Y] = ss;
q.push({ss, {X, Y}});
}
}
for (int i = 0; i < 4; i++) {
int X = x + xxx[i];
int Y = y + yyy[i];
if (X < 0 || X >= m || Y < 0 || Y >= n)continue;
if ((ty - sy) * (X - sx) >= (tx - sx) * (Y - sy)) {
if (X == tx && Y == ty && (x != sx || y != sy)) {
double ss = s + a[X][Y] + (a[x][y] + a[X][Y]) * (sqrtl(2) - 1);
if (ss < mn[X][Y]) {
mn[X][Y] = ss;
}
}
continue;
}
double ss = s + a[X][Y] + (a[x][y] + a[X][Y]) * (sqrtl(2) - 1);
if (ss < mn[X][Y]) {
mn[X][Y] = ss;
q.push({ss, {X, Y}});
}
}
}
double s2 = mn[tx][ty];
// cout << s1 << ' ' << s2 << endl;
cout << fixed << setprecision(2) << s1 + s2 - a[sx][sy] - a[tx][ty] << endl;
}
7-14 那就别担心了
题意:
给定一个有向无环图,问从起点A到终点B有多少条不同的路径,并判断是否所有从A出发的路径都能到达B。
思路:
- 用DFS标记从A可达的所有节点
- 统计可达节点的出度和入度(仅考虑可达节点之间的边)
- 计数:用拓扑排序+DP计算从A到B的路径数,dp[A]=1,按拓扑序累加
- 判断逻辑自洽:检查所有可达节点中,除了B以外是否有出度为0的节点
代码
点击查看代码
int a[N];
vector<int>g[N];
int vis[N];
int d[N];
int r[N];
int A,B;
void dfs(int x){
vis[x]=1;
if(x==B)return;
for(auto u:g[x]){
d[u]++;
r[x]++;
if(!vis[u]){
dfs(u);
}
}
}
void solve() {
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
g[x].push_back(y);
}
cin>>A>>B;
dfs(A);
queue<int>q;
a[A]=1;
vector<int>ss;
for(int i=1;i<=n;i++){
if(vis[i]&&r[i]==0){
ss.push_back(i);
// cout<<i<<endl;
}
}
q.push(A);
int f=0;
if(ss.size()==1&&ss[0]==B){
f=1;
}
while(q.size()){
auto x=q.front();
q.pop();
for(auto u:g[x]){
a[u]+=a[x];
d[u]--;
if(d[u]==0){
q.push(u);
}
}
}
cout<<a[B]<<" ";
if(f)cout<<"Yes\n";
else cout<<"No\n";
}
7-15 超能力者大赛
题意:
模拟主角按照贪心算法行动,直到击败所有对手、无法击败任何对手或时间结束。
思路:
按照题目描述的贪心算法模拟即可。需要维护每个城市中的对手集合,使用 multiset 存储能力值。每次选择目标时,遍历所有城市,找到能力值不超过主角且最大的对手,按距离、途径城市数、城市编号排序。移动需要计算最短路径,用 Floyd 预处理。战斗后合并城市中能力值不超过主角的对手。注意日期计算和边界条件。本题细节较多,详细细节见代码。
代码
点击查看代码
int a[N];
int p[N];
multiset<int>g[M];
int mn[M][M];
int mn1[M][M];
void solve() {
int n, m, k, D;
cin >> n >> m >> k >> D;
set<PII>q;
for (int i = 0; i < n; i++) {
cin >> p[i] >> a[i];
if (i)g[p[i]].insert(a[i]), q.insert({a[i], i});
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
if (i != j)mn1[i][j] = mn[i][j] = 1e18;
}
}
for (int i = 1; i <= k; i++) {
int x, y, w;
cin >> x >> y >> w;
mn[y][x] = mn[x][y] = w;
mn1[y][x] = mn1[x][y] = 1;
}
for (int k = 0; k < m; k++) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
if (mn[i][k] + mn[k][j] < mn[i][j]) {
mn[i][j] = mn[i][k] + mn[k][j];
mn1[i][j] = mn1[i][k] + mn1[k][j];
} else if (mn[i][k] + mn[k][j] == mn[i][j] && mn1[i][k] + mn1[k][j] < mn1[i][j]) {
mn1[i][j] = mn1[i][k] + mn1[k][j];
}
}
}
}
int d = 1;
int lst = -1;
while (d <= D) {
int f1 = 1;
for (int i = 0; i < m; i++) {
if (g[i].size())f1 = 0;
}
if (f1) {
cout << "WIN on day " << d << " with " << a[0] << "!" << endl;
return;
}
int f2 = 1;
for (int i = 0; i < m; i++) {
if (i == lst) continue;
if (g[i].size()) {
auto it = g[i].upper_bound(a[0]);
if (it != g[i].begin()) f2 = 0;
}
}
if (f2) {
cout << "Lose on day " << d << " with " << a[0] << "." << endl;
return;
}
int ans = -1;
int mi = -1;
for (int i = 0; i < m; i++) {
if (i == lst) continue;
if (g[i].empty()) continue;
if (mn[p[0]][i] >= 1e18) continue;
auto it = g[i].upper_bound(a[0]);
if (it == g[i].begin()) continue;
int v = *prev(it);
if (mi == -1 || v > ans || (v == ans && mn[p[0]][i] < mn[p[0]][mi]) || (v == ans && mn[p[0]][i] == mn[p[0]][mi] && mn1[p[0]][i] < mn1[p[0]][mi]) || (v == ans && mn[p[0]][i] == mn[p[0]][mi] && mn1[p[0]][i] == mn1[p[0]][mi] && i < mi)) {
ans = v;
mi = i;
}
}
if (mi == -1) {
cout << "Lose on day " << d << " with " << a[0] << "." << endl;
return;
}
lst = mi;
d += mn[p[0]][mi];
if (d-1 > D) {
break;
}
if (p[0] != mi) {
cout << "Move from " << p[0] << " to " << mi << "." << endl;
p[0] = mi;
}
if (d > D) {
break;
}
cout << "Get " << ans << " at " << mi << " on day " << d << "." << endl;
g[mi].erase(g[mi].find(ans));
a[0] += ans;
int sum = 0;
while (g[mi].size() && *g[mi].begin() <= a[0]) {
sum += *g[mi].begin();
g[mi].erase(g[mi].begin());
}
if (sum > 0) {
g[mi].insert(sum);
}
f1 = 1;
for (int i = 0; i < m; i++) {
if (g[i].size())f1 = 0;
}
if (f1) {
cout << "WIN on day " << d << " with " << a[0] << "!" << endl;
return;
}
d++;
if (d > D) {
break;
}
if (sum > 0 && sum <= a[0] && g[mi].size() == 1) {
cout << "Get " << sum << " at " << mi << " on day " << d << "." << endl;
g[mi].erase(g[mi].find(sum));
a[0] += sum;
f1 = 1;
for (int i = 0; i < m; i++) {
if (g[i].size())f1 = 0;
}
if (f1) {
cout << "WIN on day " << d << " with " << a[0] << "!" << endl;
return;
}
d++;
if (d > D) {
break;
}
}
}
cout << "Game over with " << a[0] << "." << endl;
}

浙公网安备 33010602011771号